diff --git a/.github/workflows/attach-release-assets.yml b/.github/workflows/attach-release-assets.yml index 9d505e689c..e3b8cc39db 100644 --- a/.github/workflows/attach-release-assets.yml +++ b/.github/workflows/attach-release-assets.yml @@ -13,12 +13,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2.3.1 + with: + submodules: 'true' - name: Use Node.js 18.x uses: actions/setup-node@v1 with: node-version: "18.x" - name: Install and Build OpenSCD - run: | + run: | npm i @nx/nx-linux-x64-gnu npm clean-install npm run-script build @@ -27,12 +29,12 @@ jobs: run: cp -R packages/core/doc packages/distribution/build/core-doc - name: Copy Plugin Docs to OpenSCD - run: cp -R packages/plugins/doc packages/distribution/build/plugin-doc + run: cp -R packages/oscd-official-plugins/doc packages/distribution/build/plugin-doc - name: Compress files run: tar -czf open-scd.tar.gz -C packages/distribution/build - + - name: Upload release files run: gh release upload ${{ steps.release.outputs.tag_name }} open-scd.tar.gz - env: + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 793c242aca..0224f6340c 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -12,6 +12,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2.3.1 + with: + submodules: 'true' - name: Use Node.js 18.x uses: actions/setup-node@v1 @@ -31,7 +33,7 @@ jobs: - name: Copy Plugin Docs to OpenSCD run: | - cp -R packages/plugins/doc packages/distribution/build/plugin-doc + cp -R packages/oscd-official-plugins/doc packages/distribution/build/plugin-doc - name: Deploy uses: JamesIves/github-pages-deploy-action@4.1.5 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..1739c55037 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "packages/oscd-official-plugins"] + path = packages/oscd-official-plugins + url = https://github.com/david-monichi/oscd-official-plugins.git + branch = main diff --git a/package-lock.json b/package-lock.json index af9e7b65be..91827daccb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,28 +19,6 @@ "@nx/nx-linux-x64-gnu": "18.3.4" } }, - "node_modules/@75lb/deep-merge": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", - "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", - "dev": true, - "dependencies": { - "lodash.assignwith": "^4.2.0", - "typical": "^7.1.1" - }, - "engines": { - "node": ">=12.17" - } - }, - "node_modules/@75lb/deep-merge/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -55,12 +33,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -68,30 +47,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -116,9 +95,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", - "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.8.tgz", + "integrity": "sha512-3tBctaHRW6xSub26z7n8uyOTwwUsCdvIug/oxBH9n6yCO5hMj2vwDJAo7RbBMKrM7P+W2j61zLKviJQFGOYKMg==", "dev": true, "peer": true, "dependencies": { @@ -145,9 +124,9 @@ } }, "node_modules/@babel/eslint-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.24.7.tgz", - "integrity": "sha512-lODNPJnM+OfcxxBvdmI2YmUeC0fBK3k9yET5O+1Eukr8d5VpO19c6ARtNheE2t2i/8XNYTzp3HeGEAAGZH3nnQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.25.9.tgz", + "integrity": "sha512-MWg1lz+JiP9l1fXkE0qCUVo+1XwgNRPs6GTc88hmw6qN3AdgmfTSkyHt0e1xOTsKdXW5xlh2Lsk3wrFZbW5rzQ==", "dev": true, "peer": true, "dependencies": { @@ -162,54 +141,42 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -227,19 +194,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.26.9.tgz", + "integrity": "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "engines": { @@ -259,13 +224,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -285,9 +250,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -300,80 +265,41 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -383,35 +309,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -421,14 +347,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -437,106 +363,80 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", "dev": true, "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -617,10 +517,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "dev": true, + "dependencies": { + "@babel/types": "^7.26.9" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -629,13 +532,28 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -645,12 +563,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -660,14 +578,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -677,13 +595,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -756,18 +674,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", @@ -780,21 +686,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -807,25 +698,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -835,12 +714,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -861,30 +740,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", @@ -909,30 +764,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", @@ -945,36 +776,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", @@ -992,12 +793,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1007,15 +808,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.26.8" }, "engines": { "node": ">=6.9.0" @@ -1025,14 +825,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1042,12 +842,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1057,12 +857,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1072,13 +872,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1088,14 +888,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1105,18 +904,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1127,13 +924,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1143,12 +940,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1158,13 +955,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1174,12 +971,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1188,14 +985,29 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1205,13 +1017,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1221,13 +1032,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1237,13 +1047,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1253,14 +1063,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1270,13 +1080,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1286,12 +1095,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1301,13 +1110,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1317,12 +1125,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1332,13 +1140,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1348,14 +1156,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1365,15 +1172,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1383,13 +1190,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1399,13 +1206,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1415,12 +1222,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1430,13 +1237,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1446,13 +1252,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1462,15 +1267,14 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1480,13 +1284,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1496,13 +1300,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1512,14 +1315,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1529,12 +1331,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1544,13 +1346,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1560,15 +1362,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1578,12 +1379,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1593,12 +1394,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1608,13 +1409,29 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1624,15 +1441,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.9.tgz", + "integrity": "sha512-Jf+8y9wXQbbxvVYTM8gO5oEF2POdNji0NMltEkG7FtmzD9PVz7/lxpqSdTvwsjTMU5HIHuDVNf2SOxLkWi+wPQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -1653,12 +1470,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1668,13 +1485,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1684,12 +1501,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1699,12 +1516,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", + "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1714,12 +1531,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz", + "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1729,12 +1546,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1744,13 +1561,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1760,13 +1577,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1776,13 +1593,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1792,91 +1609,79 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.26.5", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.26.3", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.26.3", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", + "@babel/plugin-transform-typeof-symbol": "^7.26.7", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "engines": { @@ -1886,6 +1691,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -1909,16 +1727,10 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", + "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1928,9 +1740,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.7.tgz", - "integrity": "sha512-eytSX6JLBY6PVAeQa2bFlDx/7Mmln/gaEpsit5a3WEvjGfiIytEsgAwuIXCPM0xvw0v0cJn3ilq0/TvXrW0kgA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.9.tgz", + "integrity": "sha512-5EVjbTegqN7RSJle6hMWYxO4voo4rI+9krITk+DWR+diJgGrjZjrIBnJhjrHYYQsFgI7j1w1QnrvV7YSKBfYGg==", "dev": true, "dependencies": { "core-js-pure": "^3.30.2", @@ -1953,33 +1765,30 @@ "dev": true }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1988,14 +1797,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2208,15 +2016,6 @@ "node": ">=4.2.0" } }, - "node_modules/@commitlint/load/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" - } - }, "node_modules/@commitlint/message": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-13.2.0.tgz", @@ -2429,16 +2228,19 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -2456,35 +2258,41 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "dependencies": { "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/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/eslintrc/node_modules/globals": { @@ -2502,21 +2310,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, "engines": { - "node": "*" + "node": ">= 4" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "node_modules/@eslint/eslintrc/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/eslintrc/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/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { @@ -2527,23 +2351,14 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@esm-bundle/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@esm-bundle/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-6Tx35wWiNw7X0nLY9RMx8v3EL8SacCFW+eEZOE9Hc+XxmU5HFE2AFEg+GehUZpiyDGwVvPH75ckGlqC7coIPnA==", - "dev": true, - "dependencies": { - "@types/chai": "^4.2.12" - } - }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -2551,9 +2366,9 @@ "dev": true }, "node_modules/@github/catalyst": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.6.0.tgz", - "integrity": "sha512-u8A+DameixqpeyHzvnJWTGj+wfiskQOYHzSiJscCWVfMkIT3rxnbHMtGh3lMthaRY21nbUOK71WcsCnCrXhBJQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.7.0.tgz", + "integrity": "sha512-qOAxrDdRZz9+v4y2WoAfh11rpRY/x4FRofPNmJyZFzAjubtzE3sCa/tAycWWufmQGoYiwwzL/qJBBgyg7avxPw==", "dev": true }, "node_modules/@hapi/bourne": { @@ -2563,14 +2378,15 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { "node": ">=10.10.0" @@ -2590,9 +2406,10 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@hutson/parse-repository-url": { @@ -2604,12 +2421,6 @@ "node": ">=6.9.0" } }, - "node_modules/@import-maps/resolve": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@import-maps/resolve/-/resolve-1.0.1.tgz", - "integrity": "sha512-tWZNBIS1CoekcwlMuyG2mr0a1Wo5lb5lEHwwWvZo+5GLgr3e9LLDTtmgtCWEwBpXMkxn9D+2W9j2FY6eZQq0tA==", - "dev": true - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2628,9 +2439,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "engines": { "node": ">=12" @@ -2651,12 +2462,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -2725,9 +2530,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -2767,9 +2572,9 @@ } }, "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==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -2931,6 +2736,86 @@ "node": ">= 10" } }, + "node_modules/@lerna/create/node_modules/@nx/nx-darwin-x64": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz", + "integrity": "sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-freebsd-x64": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz", + "integrity": "sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz", + "integrity": "sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz", + "integrity": "sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz", + "integrity": "sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@lerna/create/node_modules/@nx/nx-linux-x64-gnu": { "version": "16.10.0", "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz", @@ -2947,6 +2832,66 @@ "node": ">= 10" } }, + "node_modules/@lerna/create/node_modules/@nx/nx-linux-x64-musl": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz", + "integrity": "sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz", + "integrity": "sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz", + "integrity": "sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/create/node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/@lerna/create/node_modules/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -3136,9 +3081,9 @@ "dev": true }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", - "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", + "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==" }, "node_modules/@lit/localize": { "version": "0.11.4", @@ -5807,6 +5752,35 @@ "balanced-match": "^1.0.0" } }, + "node_modules/@nrwl/devkit/node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/@nrwl/devkit/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@nrwl/devkit/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -6044,9 +6018,9 @@ } }, "node_modules/@nx/nx-darwin-x64": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz", - "integrity": "sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-18.3.4.tgz", + "integrity": "sha512-tSzPRnNB3QdPM+KYiIuRCUtyCwcuIRC95FfP0ZB3WvfDeNxJChEAChNqmCMDE4iFvZhGuze8WqkJuIVdte+lyQ==", "cpu": [ "x64" ], @@ -6060,9 +6034,9 @@ } }, "node_modules/@nx/nx-freebsd-x64": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz", - "integrity": "sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.3.4.tgz", + "integrity": "sha512-bjSPak/d+bcR95/pxHMRhnnpHc6MnrQcG6f5AjX15Esm4JdrdQKPBmG1RybuK0WKSyD5wgVhkAGc/QQUom9l8g==", "cpu": [ "x64" ], @@ -6076,9 +6050,9 @@ } }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz", - "integrity": "sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.3.4.tgz", + "integrity": "sha512-/1HnUL7jhH0S7PxJqf6R1pk3QlAU22GY89EQV9fd+RDUtp7IyzaTlkebijTIqfxlSjC4OO3bPizaxEaxdd3uKQ==", "cpu": [ "arm" ], @@ -6092,9 +6066,9 @@ } }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz", - "integrity": "sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.3.4.tgz", + "integrity": "sha512-g/2IaB2bZTKaBNPEf9LxtIXb1XHdhh3VO9PnePIrwkkixPMLN0dTxT5Sttt75lvLP3EU1AUR5w3Aaz2Q1mYtWA==", "cpu": [ "arm64" ], @@ -6108,9 +6082,9 @@ } }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz", - "integrity": "sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.3.4.tgz", + "integrity": "sha512-MgfKLoEF6I1cCS+0ooFLEjJSSVdCYyCT9Q96IHRJntAEL8u/0GR2OUoBoLC+q1lnbIkJr/uqTJxA2Jh+sJTIbA==", "cpu": [ "arm64" ], @@ -6139,9 +6113,9 @@ } }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz", - "integrity": "sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.3.4.tgz", + "integrity": "sha512-qIJKJCYFRLVSALsvg3avjReOjuYk91Q0hFXMJ2KaEM1Y3tdzcFN0fKBiaHexgbFIUk8zJuS4dJObTqSYMXowbg==", "cpu": [ "x64" ], @@ -6155,9 +6129,9 @@ } }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz", - "integrity": "sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.3.4.tgz", + "integrity": "sha512-UxC8mRkFTPdZbKFprZkiBqVw8624xU38kI0xyooxKlFpt5lccTBwJ0B7+R8p1RoWyvh2DSyFI9VvfD7lczg1lA==", "cpu": [ "arm64" ], @@ -6171,9 +6145,9 @@ } }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz", - "integrity": "sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA==", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.3.4.tgz", + "integrity": "sha512-/RqEjNU9hxIBxRLafCNKoH3SaB2FShf+1ZnIYCdAoCZBxLJebDpnhiyrVs0lPnMj9248JbizEMdJj1+bs/bXig==", "cpu": [ "x64" ], @@ -6512,9 +6486,9 @@ "dev": true }, "node_modules/@open-wc/eslint-config": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-7.0.0.tgz", - "integrity": "sha512-iuWgs5XSPqb9zhdHIeKDSzepnjRyhoYSoS6RI+vyLMfVFRxZoqt0Yv4Q8xJ8yByXbJyakmvpukTyEKbcuIQ7Uw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", + "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", "dev": true, "dependencies": { "eslint": "^7.6.0", @@ -6522,7 +6496,7 @@ "eslint-plugin-html": "^6.0.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^2.1.0", + "eslint-plugin-lit-a11y": "^1.0.1", "eslint-plugin-no-only-tests": "^2.4.0", "eslint-plugin-wc": "^1.2.0" }, @@ -6531,432 +6505,180 @@ "eslint-plugin-html": "^6.0.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^2.1.0", + "eslint-plugin-lit-a11y": "^1.0.1", "eslint-plugin-no-only-tests": "^2.4.0", "eslint-plugin-wc": "^1.2.0" } }, - "node_modules/@open-wc/eslint-config/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "node_modules/@open-wc/lit-helpers": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@open-wc/lit-helpers/-/lit-helpers-0.5.1.tgz", + "integrity": "sha512-r/PJpYueX2CX6R/20K+1P9jtMbf6g/O076qCpqh/o6XrThJahClpbxbr8lhu0tCWIQ/SNFvLtIOmIRR7qobwWg==", + "peerDependencies": { + "lit": "^2.0.0" + } + }, + "node_modules/@open-wc/scoped-elements": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-1.3.7.tgz", + "integrity": "sha512-q/wKf4sXl7cr1kNfl8z6TLO2TrpXsFMCrfCD51sCEljltwYIXOmI6SnRXmWlnzG37A8AwHRpDXYmjPj2F4gPxA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "@open-wc/dedupe-mixin": "^1.3.0", + "lit-html": "^1.0.0" } }, - "node_modules/@open-wc/eslint-config/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "node_modules/@open-wc/semantic-dom-diff": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@open-wc/semantic-dom-diff/-/semantic-dom-diff-0.19.9.tgz", + "integrity": "sha512-iUL0OPA6PeLQVEEJ/gsgkEiwOGgK4E1KS//zTB+u+OAh0NifNTfxDxIHQa7rEGvplaq2b2zztT2yyzOzj+MlAA==", "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "@types/chai": "^4.3.1", + "@web/test-runner-commands": "^0.6.5" } }, - "node_modules/@open-wc/eslint-config/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "node_modules/@open-wc/testing": { + "version": "2.5.33", + "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-2.5.33.tgz", + "integrity": "sha512-+EJNs0i+VV4nE+BrG70l2DNGXOZTSrluruaaU06HUSk57ZlKa+kIxWmkLxCOLlbgnQgrPrQWxbs3lgB1tIx/YA==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" + "@open-wc/chai-dom-equals": "^0.12.36", + "@open-wc/semantic-dom-diff": "^0.19.3", + "@open-wc/testing-helpers": "^1.8.12", + "@types/chai": "^4.2.11", + "@types/chai-dom": "^0.0.9", + "@types/mocha": "^5.2.7", + "@types/sinon-chai": "^3.2.3", + "chai": "^4.2.0", + "chai-a11y-axe": "^1.3.1", + "chai-dom": "^1.8.1", + "mocha": "^6.2.2", + "sinon-chai": "^3.5.0" } }, - "node_modules/@open-wc/eslint-config/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "node_modules/@open-wc/testing-helpers": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-1.8.12.tgz", + "integrity": "sha512-+4exEHYvnFqI1RGDDIKFHPZ7Ws5NK1epvEku3zLaOYN3zc+huX19SndNc5+X++v8A+quN/iXbHlh80ROyNaYDA==", + "dev": true, + "dependencies": { + "@open-wc/scoped-elements": "^1.2.4", + "lit-element": "^2.2.1", + "lit-html": "^1.0.0" + } }, - "node_modules/@open-wc/eslint-config/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@openscd/addons": { + "resolved": "packages/addons", + "link": true + }, + "node_modules/@openscd/core": { + "resolved": "packages/core", + "link": true + }, + "node_modules/@openscd/distribution": { + "resolved": "packages/distribution", + "link": true + }, + "node_modules/@openscd/official-plugins": { + "resolved": "packages/oscd-official-plugins", + "link": true + }, + "node_modules/@openscd/open-scd": { + "resolved": "packages/openscd", + "link": true + }, + "node_modules/@openscd/wizards": { + "resolved": "packages/wizards", + "link": true + }, + "node_modules/@openscd/xml": { + "resolved": "packages/xml", + "link": true + }, + "node_modules/@parcel/watcher": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", + "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.2.1", + "node-gyp-build": "^4.3.0" }, "engines": { - "node": ">=0.4.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@open-wc/eslint-config/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/@parse5/tools": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@parse5/tools/-/tools-0.3.0.tgz", + "integrity": "sha512-zxRyTHkqb7WQMV8kTNBKWb1BeOFUKXBXTBWuxg9H9hfvQB3IwP6Iw2U75Ia5eyRxPNltmY7E8YAlz6zWwUnjKg==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "parse5": "^7.0.0" } }, - "node_modules/@open-wc/eslint-config/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, + "optional": true, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=14" } }, - "node_modules/@open-wc/eslint-config/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "node_modules/@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", "dev": true, "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" }, "engines": { - "node": ">= 6" + "node": ">=14.0.0" }, "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + }, + "rollup": { + "optional": true + } } }, - "node_modules/@open-wc/eslint-config/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/@rollup/plugin-commonjs": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz", + "integrity": "sha512-LuNyypCP3msCGVQJ7ki8PqYdpjfEkE/xtFa5DqlF+7IBD0JsfMZ87C58heSwIMint58sAUZbt3ITqOmdQv/dXw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" }, "engines": { - "node": ">=6" + "node": ">= 8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/@open-wc/eslint-config/node_modules/eslint-utils/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/@open-wc/eslint-config/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@open-wc/eslint-config/node_modules/espree/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/@open-wc/eslint-config/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@open-wc/eslint-config/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@open-wc/eslint-config/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/@open-wc/eslint-config/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/@open-wc/eslint-config/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@open-wc/lit-helpers": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@open-wc/lit-helpers/-/lit-helpers-0.5.1.tgz", - "integrity": "sha512-r/PJpYueX2CX6R/20K+1P9jtMbf6g/O076qCpqh/o6XrThJahClpbxbr8lhu0tCWIQ/SNFvLtIOmIRR7qobwWg==", - "peerDependencies": { - "lit": "^2.0.0" - } - }, - "node_modules/@open-wc/scoped-elements": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.2.4.tgz", - "integrity": "sha512-12X4F4QGPWcvPbxAiJ4v8wQFCOu+laZHRGfTrkoj+3JzACCtuxHG49YbuqVzQ135QPKCuhP9wA0kpGGEfUegyg==", - "dev": true, - "dependencies": { - "@lit/reactive-element": "^1.0.0 || ^2.0.0", - "@open-wc/dedupe-mixin": "^1.4.0" - } - }, - "node_modules/@open-wc/semantic-dom-diff": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@open-wc/semantic-dom-diff/-/semantic-dom-diff-0.19.9.tgz", - "integrity": "sha512-iUL0OPA6PeLQVEEJ/gsgkEiwOGgK4E1KS//zTB+u+OAh0NifNTfxDxIHQa7rEGvplaq2b2zztT2yyzOzj+MlAA==", - "dev": true, - "dependencies": { - "@types/chai": "^4.3.1", - "@web/test-runner-commands": "^0.6.5" - } - }, - "node_modules/@open-wc/testing": { - "version": "3.0.0-next.5", - "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-3.0.0-next.5.tgz", - "integrity": "sha512-n2NrCGql3daWKOuyvdwKqdnm2ArOch+U7yIuvLZGTwtlMXlvZjOAln3CKZCWEmN5lXcgIAb5czeY7CzOmP8QWg==", - "dev": true, - "dependencies": { - "@esm-bundle/chai": "^4.3.4", - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.5-next.2", - "@open-wc/testing-helpers": "^2.0.0-next.2", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/sinon-chai": "^3.2.3", - "chai-a11y-axe": "^1.3.2-next.0" - } - }, - "node_modules/@open-wc/testing-helpers": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-2.3.2.tgz", - "integrity": "sha512-uZMGC/C1m5EiwQsff6KMmCW25TYMQlJt4ilAWIjnelWGFg9HPUiLnlFvAas3ESUP+4OXLO8Oft7p4mHvbYvAEQ==", - "dev": true, - "dependencies": { - "@open-wc/scoped-elements": "^2.2.4", - "lit": "^2.0.0 || ^3.0.0", - "lit-html": "^2.0.0 || ^3.0.0" - } - }, - "node_modules/@open-wc/testing-helpers/node_modules/lit-html": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.4.tgz", - "integrity": "sha512-yKKO2uVv7zYFHlWMfZmqc+4hkmSbFp8jgjdZY9vvR9jr4J8fH6FUMXhr+ljfELgmjpvlF7Z1SJ5n5/Jeqtc9YA==", - "dev": true, - "dependencies": { - "@types/trusted-types": "^2.0.2" - } - }, - "node_modules/@openscd/addons": { - "resolved": "packages/addons", - "link": true - }, - "node_modules/@openscd/core": { - "resolved": "packages/core", - "link": true - }, - "node_modules/@openscd/distribution": { - "resolved": "packages/distribution", - "link": true - }, - "node_modules/@openscd/open-scd": { - "resolved": "packages/openscd", - "link": true - }, - "node_modules/@openscd/plugins": { - "resolved": "packages/plugins", - "link": true - }, - "node_modules/@openscd/wizards": { - "resolved": "packages/wizards", - "link": true - }, - "node_modules/@openscd/xml": { - "resolved": "packages/xml", - "link": true - }, - "node_modules/@parcel/watcher": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", - "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parse5/tools": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@parse5/tools/-/tools-0.3.0.tgz", - "integrity": "sha512-zxRyTHkqb7WQMV8kTNBKWb1BeOFUKXBXTBWuxg9H9hfvQB3IwP6Iw2U75Ia5eyRxPNltmY7E8YAlz6zWwUnjKg==", - "dev": true, - "dependencies": { - "parse5": "^7.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@rollup/plugin-babel": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", - "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - }, - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz", - "integrity": "sha512-LuNyypCP3msCGVQJ7ki8PqYdpjfEkE/xtFa5DqlF+7IBD0JsfMZ87C58heSwIMint58sAUZbt3ITqOmdQv/dXw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^2.30.0" + "peerDependencies": { + "rollup": "^2.30.0" } }, "node_modules/@rollup/plugin-commonjs/node_modules/@rollup/pluginutils": { @@ -6997,6 +6719,18 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/@rollup/plugin-commonjs/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/@rollup/plugin-inject": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz", @@ -7049,6 +6783,18 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/@rollup/plugin-inject/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/@rollup/plugin-json": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", @@ -7090,10 +6836,22 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", - "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "node_modules/@rollup/plugin-json/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/@rollup/plugin-node-resolve": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", + "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -7139,6 +6897,18 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, + "node_modules/@rollup/plugin-node-resolve/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/@rollup/plugin-replace": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", @@ -7187,14 +6957,14 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -7208,6 +6978,12 @@ } } }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, "node_modules/@sigstore/bundle": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz", @@ -7318,23 +7094,21 @@ } }, "node_modules/@sigstore/sign/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -7384,9 +7158,9 @@ } }, "node_modules/@sigstore/sign/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7518,39 +7292,39 @@ "type-detect": "4.0.8" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "node_modules/@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "@sinonjs/commons": "^3.0.1" } }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "dev": true }, "node_modules/@snowpack/plugin-typescript": { @@ -7640,9 +7414,9 @@ } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7721,9 +7495,9 @@ } }, "node_modules/@types/browserslist": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@types/browserslist/-/browserslist-4.15.0.tgz", - "integrity": "sha512-h9LyKErRGZqMsHh9bd+FE8yCIal4S0DxKTOeui56VgVXqa66TKiuaIUxCAI7c1O0LjaUzOTcsMyOpO9GetozRA==", + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/@types/browserslist/-/browserslist-4.15.4.tgz", + "integrity": "sha512-gmSSW1GuQN9ZTDs0nmCT1ybj76N/+mSJAgVaNoEsxCCKs7yblsZsKY3Vt/L2VKtHL5dysWhwPDaawCr0y1gt0Q==", "deprecated": "This is a stub types definition. browserslist provides its own type definitions, so you do not need this installed.", "dev": true, "dependencies": { @@ -7755,9 +7529,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", "dev": true }, "node_modules/@types/chai-dom": { @@ -7831,9 +7605,9 @@ "dev": true }, "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/etag": { @@ -7846,21 +7620,21 @@ } }, "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==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", "dev": true, "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", + "@types/express-serve-static-core": "^5.0.0", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", - "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", "dev": true, "dependencies": { "@types/node": "*", @@ -7870,9 +7644,9 @@ } }, "node_modules/@types/http-assert": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", - "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.6.tgz", + "integrity": "sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==", "dev": true }, "node_modules/@types/http-cache-semantics": { @@ -8057,19 +7831,16 @@ } }, "node_modules/@types/mocha": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", "dev": true }, "node_modules/@types/node": { - "version": "18.19.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", - "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } + "version": "16.18.126", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", + "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==", + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", @@ -8114,9 +7885,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", "dev": true }, "node_modules/@types/range-parser": { @@ -8171,9 +7942,9 @@ } }, "node_modules/@types/sinon": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", + "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -8229,32 +8000,30 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -8286,28 +8055,42 @@ "eslint": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/parser": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -8316,60 +8099,59 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "*" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8378,23 +8160,20 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8404,40 +8183,25 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://opencollective.com/eslint" } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { "type": "opencollective", @@ -8445,21 +8209,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", @@ -8497,14 +8261,14 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8514,26 +8278,100 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@web/browser-logs": { - "version": "0.2.6", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true + }, + "node_modules/@web/browser-logs": { + "version": "0.2.6", "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.2.6.tgz", "integrity": "sha512-CNjNVhd4FplRY8PPWIAt02vAowJAVcOoTNrR/NNb/o9pka7yI9qdjpWrWhEbPr2pOXonWb52AeAgdK66B8ZH7w==", "dev": true, @@ -8615,9 +8453,9 @@ } }, "node_modules/@web/dev-server-core/node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true }, "node_modules/@web/dev-server-core/node_modules/lru-cache": { @@ -8638,6 +8476,18 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, + "node_modules/@web/dev-server-core/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/@web/dev-server-core/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -8690,9 +8540,9 @@ } }, "node_modules/@web/dev-server-esbuild/node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true }, "node_modules/@web/dev-server-esbuild/node_modules/isbinaryfile": { @@ -8725,120 +8575,24 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/@web/dev-server-esbuild/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/@web/dev-server-import-maps": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@web/dev-server-import-maps/-/dev-server-import-maps-0.2.1.tgz", - "integrity": "sha512-iGM7s4qenmTDUWC2iV0HoQ1NR5lAyRxVHOpWzTsFH/TnUZzP+YuL6QIFtB2v2v7URfhGL2l2WPIibmliToITcg==", - "dev": true, - "dependencies": { - "@import-maps/resolve": "^1.0.1", - "@types/parse5": "^6.0.1", - "@web/dev-server-core": "^0.7.2", - "@web/parse5-utils": "^2.1.0", - "parse5": "^6.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web/dev-server-import-maps/node_modules/@web/dev-server-core": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.5.tgz", - "integrity": "sha512-Da65zsiN6iZPMRuj4Oa6YPwvsmZmo5gtPWhW2lx3GTUf5CAEapjVpZVlUXnKPL7M7zRuk72jSsIl8lo+XpTCtw==", - "dev": true, - "dependencies": { - "@types/koa": "^2.11.6", - "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.1.0", - "chokidar": "^4.0.1", - "clone": "^2.1.2", - "es-module-lexer": "^1.0.0", - "get-stream": "^6.0.0", - "is-stream": "^2.0.0", - "isbinaryfile": "^5.0.0", - "koa": "^2.13.0", - "koa-etag": "^4.0.0", - "koa-send": "^5.0.1", - "koa-static": "^5.0.0", - "lru-cache": "^8.0.4", - "mime-types": "^2.1.27", - "parse5": "^6.0.1", - "picomatch": "^2.2.2", - "ws": "^7.5.10" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web/dev-server-import-maps/node_modules/@web/parse5-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", - "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", - "dev": true, - "dependencies": { - "@types/parse5": "^6.0.1", - "parse5": "^6.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web/dev-server-import-maps/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/@web/dev-server-esbuild/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": { - "readdirp": "^4.0.1" - }, "engines": { - "node": ">= 14.16.0" + "node": ">=8.6" }, "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@web/dev-server-import-maps/node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "dev": true - }, - "node_modules/@web/dev-server-import-maps/node_modules/lru-cache": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", - "dev": true, - "engines": { - "node": ">=16.14" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@web/dev-server-import-maps/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "node_modules/@web/dev-server-esbuild/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/@web/dev-server-import-maps/node_modules/readdirp": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", - "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", - "dev": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@web/dev-server-rollup": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.4.1.tgz", @@ -8944,6 +8698,18 @@ "node": ">=12.0.0" } }, + "node_modules/@web/polyfills-loader/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/@web/polyfills-loader/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -8951,9 +8717,9 @@ "dev": true }, "node_modules/@web/polyfills-loader/node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -8983,6 +8749,18 @@ "node": ">=12.0.0" } }, + "node_modules/@web/rollup-plugin-html/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/@web/rollup-plugin-html/node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", @@ -9032,9 +8810,9 @@ "dev": true }, "node_modules/@web/rollup-plugin-html/node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -9177,6 +8955,18 @@ "node": ">=12.0.0" } }, + "node_modules/@web/test-runner-core/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/@web/test-runner-coverage-v8": { "version": "0.4.9", "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.4.9.tgz", @@ -9192,6 +8982,18 @@ "node": ">=12.0.0" } }, + "node_modules/@web/test-runner-coverage-v8/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/@web/test-runner-mocha": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.7.5.tgz", @@ -9205,6 +9007,12 @@ "node": ">=12.0.0" } }, + "node_modules/@web/test-runner-mocha/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true + }, "node_modules/@web/test-runner-playwright": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.8.10.tgz", @@ -9463,9 +9271,9 @@ "dev": true }, "node_modules/abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz", + "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==", "dev": true }, "node_modules/accepts": { @@ -9487,9 +9295,9 @@ "integrity": "sha512-xU/9r94WKwjwEOjdfs6oVk2Dqc6X63eF2ECvKIMm/JCK1PDbXXdBYi5sQx110tR2sY4f96iXxyvscfT9qeI1RQ==" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -9508,10 +9316,25 @@ } }, "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==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { "node": ">=0.4.0" } @@ -9544,9 +9367,9 @@ } }, "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "dev": true, "dependencies": { "humanize-ms": "^1.2.1" @@ -9635,9 +9458,9 @@ } }, "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.3.tgz", + "integrity": "sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==", "dev": true }, "node_modules/ansi-styles": { @@ -9674,8 +9497,20 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "2.0.0", + "node_modules/anymatch/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/aproba": { + "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true @@ -9707,12 +9542,16 @@ "dev": true }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, "dependencies": { - "dequal": "^2.0.3" + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" } }, "node_modules/array-back": { @@ -9725,13 +9564,13 @@ } }, "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==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -9814,15 +9653,15 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9832,15 +9671,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -9871,19 +9710,18 @@ } }, "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "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" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -9962,6 +9800,15 @@ "lodash": "^4.17.14" } }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -10002,24 +9849,24 @@ } }, "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", "dev": true }, "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dev": true, "dependencies": { "follow-redirects": "^1.15.6", @@ -10034,13 +9881,13 @@ "dev": true }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -10057,25 +9904,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -10371,9 +10218,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -10390,10 +10237,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -10458,9 +10305,9 @@ "dev": true }, "node_modules/bufferutil": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", - "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -10712,16 +10559,44 @@ } }, "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==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "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" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -10800,9 +10675,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001629", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001629.tgz", - "integrity": "sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==", + "version": "1.0.30001700", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", + "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", "dev": true, "funding": [ { @@ -10835,9 +10710,9 @@ } }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -10846,7 +10721,7 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" @@ -10862,9 +10737,9 @@ } }, "node_modules/chai-dom": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.12.0.tgz", - "integrity": "sha512-pLP8h6IBR8z1AdeQ+EMcJ7dXPdsax/1Q7gdGZjsnAmSBl3/gItQUYSCo32br1qOy4SlcBjvqId7ilAf3uJ2K1w==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.12.1.tgz", + "integrity": "sha512-tvz+D0PJue2VHXRec3udgP/OeeXBiePU3VH6JhEnHQJYzvNzR2nUvEykA9dXVS76JvaUENSOYH8Ufr0kZSnlCQ==", "dev": true, "engines": { "node": ">= 0.12.0" @@ -11058,15 +10933,24 @@ } }, "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true }, "node_modules/clean-css": { @@ -11148,71 +11032,21 @@ } }, "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", @@ -11372,9 +11206,9 @@ } }, "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", "dev": true }, "node_modules/columnify": { @@ -11418,14 +11252,14 @@ } }, "node_modules/command-line-usage": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", - "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", + "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", "dev": true, "dependencies": { "array-back": "^6.2.2", "chalk-template": "^0.4.0", - "table-layout": "^3.0.0", + "table-layout": "^4.1.0", "typical": "^7.1.1" }, "engines": { @@ -11433,9 +11267,9 @@ } }, "node_modules/command-line-usage/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", + "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", "dev": true, "engines": { "node": ">=12.17" @@ -11527,30 +11361,25 @@ } }, "node_modules/concurrently": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.6.0.tgz", - "integrity": "sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", + "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", "dev": true, "dependencies": { "chalk": "^4.1.0", - "date-fns": "^2.29.1", + "date-fns": "^2.16.1", "lodash": "^4.17.21", - "rxjs": "^7.0.0", - "shell-quote": "^1.7.3", + "rxjs": "^6.6.3", "spawn-command": "^0.0.2-1", "supports-color": "^8.1.0", "tree-kill": "^1.2.2", - "yargs": "^17.3.1" + "yargs": "^16.2.0" }, "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" + "concurrently": "bin/concurrently.js" }, "engines": { - "node": "^12.20.0 || ^14.13.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + "node": ">=10.0.0" } }, "node_modules/concurrently/node_modules/supports-color": { @@ -11568,33 +11397,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/concurrently/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/concurrently/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/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -12150,9 +11952,9 @@ } }, "node_modules/core-js-bundle": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.37.1.tgz", - "integrity": "sha512-Bt9sorQku7bA6xoaY2NYdeaEnitLg9peHJ+eAijrARCQ5FhkoUW1eF4oI35XfP9kyeyljw71uCud4ju8tjGhsg==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.40.0.tgz", + "integrity": "sha512-qsrCnO7hapeqxIJzEiVQRuoo8SYqEPPE+AvDq7tqpM9g72q+Er0ajOI/LDG01f9jA2tV/OACuHtGZlQocBARGA==", "dev": true, "hasInstallScript": true, "funding": { @@ -12161,12 +11963,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", "dev": true, "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -12174,9 +11976,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz", + "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==", "dev": true, "hasInstallScript": true, "funding": { @@ -12241,9 +12043,9 @@ } }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -12354,14 +12156,14 @@ } }, "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==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12371,29 +12173,29 @@ } }, "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==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "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==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -12436,12 +12238,12 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -12599,7 +12401,6 @@ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -12719,15 +12520,6 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -13038,6 +12830,20 @@ "node": ">=4" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -13100,9 +12906,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.792", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", - "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==", + "version": "1.5.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.103.tgz", + "integrity": "sha512-P6+XzIkfndgsrjROJWfSvVEgNHtPgbhVyTkwLjUM2HU/h7pZRORgaTlHqfAikqxKmdJMLW8fftrdGWbd/Ds0FA==", "dev": true }, "node_modules/email-addresses": { @@ -13112,9 +12918,9 @@ "dev": true }, "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "node_modules/encodeurl": { @@ -13159,12 +12965,13 @@ } }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" @@ -13225,57 +13032,62 @@ "dev": true }, "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==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "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", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "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", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "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", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "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", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "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" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -13291,13 +13103,10 @@ "dev": true }, "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==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -13596,6 +13405,18 @@ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "dev": true }, + "node_modules/es-dev-server/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/es-dev-server/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -13679,15 +13500,15 @@ "dev": true }, "node_modules/es-module-shims": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-module-shims/-/es-module-shims-1.10.0.tgz", - "integrity": "sha512-3PmuShQBd9d8pulTFx6L7HKgncnZ1oeSSbrEfnUasb3Tv974BAvyFtW1HLPJSkh5fCaU9JNZbBzPdbxSwg2zqA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/es-module-shims/-/es-module-shims-1.10.1.tgz", + "integrity": "sha512-HSSkRLkqFEyX6GrCAHrSOR5iz/QzQJRqZUF7bFJOZ4aoSw0WoSggfsTIGN2yFbF8v6xjQFhT4HGP6b+0qQZmEQ==", "dev": true }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "dependencies": { "es-errors": "^1.3.0" @@ -13697,37 +13518,41 @@ } }, "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==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "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==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -13747,9 +13572,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -13911,7 +13736,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", "dev": true, "hasInstallScript": true, "optional": true, @@ -13931,6 +13755,18 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/esinstall/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/esinstall/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -13972,60 +13808,81 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.3.2", + "debug": "^4.0.1", "doctrine": "^3.0.0", + "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.0.4", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^10.12.0 || >=12.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-airbnb-base": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1" + } + }, "node_modules/eslint-config-prettier": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", @@ -14059,9 +13916,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -14109,34 +13966,36 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -14182,9 +14041,9 @@ } }, "node_modules/eslint-plugin-lit": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.14.0.tgz", - "integrity": "sha512-J4w+CgO31621GreLFCdTUbTr5yeV2/RJ/M0myw0dykD5p9FGGIRLityQiNa6SG+JpVbmeQTQPJy4pNFmiurJ/w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.15.0.tgz", + "integrity": "sha512-Yhr2MYNz6Ln8megKcX503aVZQln8wsywCG49g0heiJ/Qr5UjkE4pGr4Usez2anNcc7NvlvHbQWMYwWcgH3XRKA==", "dev": true, "dependencies": { "parse5": "^6.0.1", @@ -14199,20 +14058,20 @@ } }, "node_modules/eslint-plugin-lit-a11y": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-2.4.1.tgz", - "integrity": "sha512-UljRja/2cVrNtgnCDj5sCT3Larxda4mGqbsPhlksvECo0+KCD8EuUori/P6wFeFqk+pHlkIC3W200E5q85E3VQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", + "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", "dev": true, "dependencies": { - "aria-query": "^5.1.3", + "aria-query": "^4.2.2", "axe-core": "^4.3.3", "axobject-query": "^2.2.0", "dom5": "^3.0.1", - "emoji-regex": "^10.2.1", - "eslint-plugin-lit": "^1.6.0", + "emoji-regex": "^9.2.0", + "eslint": "^7.6.0", "eslint-rule-extender": "0.0.1", - "language-tags": "^1.0.5", - "parse5": "^7.1.2", + "intl-list-format": "^1.0.3", + "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.1", "requireindex": "~1.2.0" }, @@ -14220,6 +14079,12 @@ "eslint": ">= 5" } }, + "node_modules/eslint-plugin-lit-a11y/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, "node_modules/eslint-plugin-lit/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -14320,53 +14185,46 @@ "node": ">=10" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@babel/highlight": "^7.10.4" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "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, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "node_modules/eslint/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/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, "engines": { - "node": ">=4.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/eslint/node_modules/eslint-utils/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, - "dependencies": { - "is-glob": "^4.0.3" - }, "engines": { - "node": ">=10.13.0" + "node": ">=4" } }, "node_modules/eslint/node_modules/globals": { @@ -14384,18 +14242,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/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/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "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": { - "brace-expansion": "^1.1.7" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": "*" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/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/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -14409,32 +14283,26 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "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": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=4" } }, "node_modules/esprima": { @@ -14451,9 +14319,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -14555,9 +14423,9 @@ } }, "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", "dev": true }, "node_modules/extend": { @@ -14625,25 +14493,19 @@ ] }, "node_modules/fast-check": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.19.0.tgz", - "integrity": "sha512-CO2JX/8/PT9bDGO1iXa5h5ey1skaKI1dvecERyhH4pp3PGjwd3KIjMAXEg79Ps9nclsdt4oPbfqiAnLU0EwrAQ==", + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", + "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], "dependencies": { - "pure-rand": "^6.1.0" + "pure-rand": "^5.0.1" }, "engines": { "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" } }, "node_modules/fast-deep-equal": { @@ -14653,16 +14515,16 @@ "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==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "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" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -14680,10 +14542,26 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -14698,20 +14576,6 @@ "pend": "~1.2.0" } }, - "node_modules/fdir": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-5.3.0.tgz", - "integrity": "sha512-BtE53+jaa7nNHT+gPdfU6cFAXOJUWDs2b5GFox8dtl6zLXmfNf/N6im69b9nqNNwDyl27mpIWX8qR7AafWzSdQ==", - "dev": true, - "peerDependencies": { - "picomatch": "2.x" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -14949,15 +14813,15 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -14975,18 +14839,24 @@ } }, "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==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -15021,13 +14891,14 @@ } }, "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.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -15050,9 +14921,9 @@ "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==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -15105,15 +14976,17 @@ } }, "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==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -15157,6 +15030,15 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/gauge/node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/generic-names": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-4.0.0.tgz", @@ -15194,16 +15076,21 @@ } }, "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==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -15288,6 +15175,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", @@ -15301,14 +15201,14 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -15605,12 +15505,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15725,10 +15625,13 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15755,10 +15658,13 @@ } }, "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==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -15767,9 +15673,9 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" @@ -16143,70 +16049,18 @@ } }, "node_modules/husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", "dev": true, - "hasInstallScript": true, - "dependencies": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, "bin": { - "husky-run": "bin/run.js", - "husky-upgrade": "lib/upgrader/bin.js" + "husky": "lib/bin.js" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" - } - }, - "node_modules/husky/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/husky/node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/husky/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" + "url": "https://github.com/sponsors/typicode" } }, "node_modules/iconv-lite": { @@ -16266,9 +16120,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "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" @@ -16308,9 +16162,9 @@ } }, "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==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "dependencies": { "parent-module": "^1.0.0", @@ -16435,9 +16289,9 @@ } }, "node_modules/init-package-json/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -16512,12 +16366,20 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/inquirer/node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/internal-ip": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", "dev": true, - "license": "MIT", "dependencies": { "default-gateway": "^6.0.0", "ipaddr.js": "^1.9.1", @@ -16532,14 +16394,14 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -16584,7 +16446,6 @@ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -16594,19 +16455,19 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } }, "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==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -16621,13 +16482,35 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16646,13 +16529,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16723,39 +16606,29 @@ "is-ci": "bin.js" } }, - "node_modules/is-ci/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, "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==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-view": { - "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==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -16766,12 +16639,13 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16804,25 +16678,40 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -16894,7 +16783,6 @@ "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", "dev": true, - "license": "MIT", "dependencies": { "ip-regex": "^4.0.0" }, @@ -16908,16 +16796,10 @@ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", "dev": true }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "node_modules/is-negative-zero": { + "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "engines": { "node": ">= 0.4" @@ -16926,6 +16808,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "node_modules/is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", @@ -16945,12 +16833,13 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -17011,13 +16900,15 @@ } }, "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==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -17035,13 +16926,25 @@ "node": ">=0.10.0" } }, - "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==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -17051,9 +16954,9 @@ } }, "node_modules/is-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", "dev": true, "dependencies": { "protocols": "^2.0.1" @@ -17069,12 +16972,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -17084,12 +16988,14 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -17111,12 +17017,12 @@ } }, "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==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -17161,13 +17067,44 @@ "assert": "^1.4.1" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -17198,9 +17135,9 @@ "dev": true }, "node_modules/isbinaryfile": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", - "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", + "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", "dev": true, "engines": { "node": ">= 18.0.0" @@ -17267,16 +17204,13 @@ } }, "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -17285,9 +17219,9 @@ } }, "node_modules/jake": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", - "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "dev": true, "dependencies": { "async": "^3.2.3", @@ -17303,9 +17237,9 @@ } }, "node_modules/jake/node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true }, "node_modules/jake/node_modules/minimatch": { @@ -17440,15 +17374,15 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/jshint": { @@ -17586,9 +17520,9 @@ } }, "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", + "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", "dev": true, "engines": { "node": "*" @@ -17683,9 +17617,9 @@ } }, "node_modules/koa": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", - "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.4.tgz", + "integrity": "sha512-7fNBIdrU2PEgLljXoPWoyY4r1e+ToWCmzS/wwMPbUNs7X+5MMET1ObhJBlUkF5uZG9B6QhM2zS1TsH6adegkiQ==", "dev": true, "dependencies": { "accepts": "^1.3.5", @@ -17967,6 +17901,86 @@ "node": ">= 10" } }, + "node_modules/lerna/node_modules/@nx/nx-darwin-x64": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz", + "integrity": "sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-freebsd-x64": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz", + "integrity": "sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz", + "integrity": "sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz", + "integrity": "sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz", + "integrity": "sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/lerna/node_modules/@nx/nx-linux-x64-gnu": { "version": "16.10.0", "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz", @@ -17983,6 +17997,66 @@ "node": ">= 10" } }, + "node_modules/lerna/node_modules/@nx/nx-linux-x64-musl": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz", + "integrity": "sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz", + "integrity": "sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz", + "integrity": "sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lerna/node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/lerna/node_modules/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -18207,9 +18281,9 @@ } }, "node_modules/libnpmaccess/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -18261,25 +18335,10 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/libnpmpublish/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, "node_modules/libnpmpublish/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -18392,484 +18451,247 @@ } }, "node_modules/lint-staged": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.3.0.tgz", - "integrity": "sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", + "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", "dev": true, "dependencies": { - "chalk": "5.3.0", - "commander": "11.0.0", - "debug": "4.3.4", - "execa": "7.2.0", - "lilconfig": "2.1.0", - "listr2": "6.6.1", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.1" + "cli-truncate": "2.1.0", + "colorette": "^1.4.0", + "commander": "^8.2.0", + "cosmiconfig": "^7.0.1", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "execa": "^5.1.1", + "listr2": "^3.12.2", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "3.3.0", + "supports-color": "8.1.1" }, "bin": { "lint-staged": "bin/lint-staged.js" }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - }, "funding": { "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/lint-staged/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 12" } }, - "node_modules/lint-staged/node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/lint-staged/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/lint-staged/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "@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": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=10" } }, "node_modules/lint-staged/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "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.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.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": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/lint-staged/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/lint-staged/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/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/lint-staged/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==", + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } } }, - "node_modules/lint-staged/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/listr2/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/listr2/node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" + "tslib": "^2.1.0" } }, - "node_modules/lint-staged/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==", + "node_modules/listr2/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": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/lint-staged/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, + "node_modules/lit": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz", + "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==", "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@lit/reactive-element": "^1.6.0", + "lit-element": "^3.3.0", + "lit-html": "^2.8.0" } }, - "node_modules/lint-staged/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, + "node_modules/lit-element": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.5.1.tgz", + "integrity": "sha512-ogu7PiJTA33bEK0xGu1dmaX5vhcRjBXCFexPja0e7P7jqLhTpNKYRPmE+GmiCaRVAbiQKGkUgkh/i6+bh++dPQ==", "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "lit-html": "^1.1.1" } }, - "node_modules/lint-staged/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==", + "node_modules/lit-html": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.4.1.tgz", + "integrity": "sha512-B9btcSgPYb1q4oSOb/PrOT6Z/H+r6xuNzfH4lFli/AWhYwdtrgQkQWBbIc6mdnf6E2IL3gDXdkkqNktpU0OZQA==" + }, + "node_modules/lit-translate": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/lit-translate/-/lit-translate-1.2.1.tgz", + "integrity": "sha512-jykKpkdRX0lx3JYq9jUMzVs02ISClOe2wxyPHat5wVKPyBRJQxgXxLxj1AbpuLNBCDZKEysMBpeJ1z0Y35Bk2Q==", + "dependencies": { + "lit-html": "^1.2.1" + } + }, + "node_modules/lit/node_modules/lit-element": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", + "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.1.0", + "@lit/reactive-element": "^1.3.0", + "lit-html": "^2.8.0" + } + }, + "node_modules/lit/node_modules/lit-html": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", + "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/lint-staged/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==", + "node_modules/load-json-file/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": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/listr2": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", - "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "dev": true, - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "node": ">= 12.13.0" } }, - "node_modules/listr2/node_modules/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "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": { - "type-fest": "^1.0.2" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/listr2/node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/listr2/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "node_modules/listr2/node_modules/log-update": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "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" - } - }, - "node_modules/listr2/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/listr2/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/listr2/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "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" - } - }, - "node_modules/lit": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz", - "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==", - "dependencies": { - "@lit/reactive-element": "^1.6.0", - "lit-element": "^3.3.0", - "lit-html": "^2.8.0" - } - }, - "node_modules/lit-element": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.5.1.tgz", - "integrity": "sha512-ogu7PiJTA33bEK0xGu1dmaX5vhcRjBXCFexPja0e7P7jqLhTpNKYRPmE+GmiCaRVAbiQKGkUgkh/i6+bh++dPQ==", - "dependencies": { - "lit-html": "^1.1.1" - } - }, - "node_modules/lit-html": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.4.1.tgz", - "integrity": "sha512-B9btcSgPYb1q4oSOb/PrOT6Z/H+r6xuNzfH4lFli/AWhYwdtrgQkQWBbIc6mdnf6E2IL3gDXdkkqNktpU0OZQA==" - }, - "node_modules/lit-translate": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/lit-translate/-/lit-translate-1.2.1.tgz", - "integrity": "sha512-jykKpkdRX0lx3JYq9jUMzVs02ISClOe2wxyPHat5wVKPyBRJQxgXxLxj1AbpuLNBCDZKEysMBpeJ1z0Y35Bk2Q==", - "dependencies": { - "lit-html": "^1.2.1" - } - }, - "node_modules/lit/node_modules/lit-element": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", - "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.1.0", - "@lit/reactive-element": "^1.3.0", - "lit-html": "^2.8.0" - } - }, - "node_modules/lit/node_modules/lit-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", - "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", - "dependencies": { - "@types/trusted-types": "^2.0.2" - } - }, - "node_modules/load-json-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", - "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "parse-json": "^5.0.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/load-json-file/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/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "dev": true, - "engines": { - "node": ">= 12.13.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" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -18881,12 +18703,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.assignwith": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", - "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", - "dev": true - }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -18903,6 +18719,7 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true }, "node_modules/lodash.ismatch": { @@ -18942,25 +18759,92 @@ "dev": true }, "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "chalk": "^2.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "node_modules/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/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/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "dependencies": { "ansi-escapes": "^4.3.0", @@ -18975,15 +18859,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/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/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -19044,12 +18919,12 @@ "dev": true }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -19164,6 +19039,15 @@ "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", "dev": true }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -19364,9 +19248,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -19376,6 +19260,18 @@ "node": ">=8.6" } }, + "node_modules/micromatch/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/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -19389,9 +19285,9 @@ } }, "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==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", "dev": true, "engines": { "node": ">= 0.6" @@ -19409,6 +19305,15 @@ "node": ">= 0.6" } }, + "node_modules/mime-types/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/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -19534,9 +19439,9 @@ } }, "node_modules/minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz", + "integrity": "sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==", "dev": true, "dependencies": { "jsonparse": "^1.3.1", @@ -19672,12 +19577,12 @@ } }, "node_modules/mocha/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==", + "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": ">=4" + "node": ">=6" } }, "node_modules/mocha/node_modules/ansi-styles": { @@ -19710,32 +19615,6 @@ "node": ">=6" } }, - "node_modules/mocha/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/mocha/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/mocha/node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -19747,41 +19626,6 @@ "wrap-ansi": "^5.1.0" } }, - "node_modules/mocha/node_modules/cliui/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/mocha/node_modules/cliui/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" - } - }, - "node_modules/mocha/node_modules/cliui/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -19905,18 +19749,6 @@ "node": ">=6" } }, - "node_modules/mocha/node_modules/log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "dependencies": { - "chalk": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -20006,28 +19838,29 @@ "dev": true }, "node_modules/mocha/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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": "^4.0.0" + "strip-ansi": "^5.1.0" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/mocha/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==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/mocha/node_modules/strip-json-comments": { @@ -20063,15 +19896,6 @@ "which": "bin/which" } }, - "node_modules/mocha/node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, "node_modules/mocha/node_modules/wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -20086,41 +19910,6 @@ "node": ">=6" } }, - "node_modules/mocha/node_modules/wrap-ansi/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/mocha/node_modules/wrap-ansi/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" - } - }, - "node_modules/mocha/node_modules/wrap-ansi/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", @@ -20155,54 +19944,19 @@ "decamelize": "^1.2.0" } }, - "node_modules/mocha/node_modules/yargs/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==", + "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": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs/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" - } - }, - "node_modules/mocha/node_modules/yargs/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "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": ">=0.10.0" } }, "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==", + "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/multimatch": { @@ -20248,9 +20002,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -20413,9 +20167,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -20461,9 +20215,9 @@ "dev": true }, "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==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/nopt": { @@ -20678,9 +20432,9 @@ } }, "node_modules/npm-pick-manifest/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -20815,23 +20569,21 @@ } }, "node_modules/npm-registry-fetch/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -20846,9 +20598,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -20893,9 +20645,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -21122,141 +20874,41 @@ } } }, - "node_modules/nx/node_modules/@nx/nx-darwin-x64": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-18.3.4.tgz", - "integrity": "sha512-tSzPRnNB3QdPM+KYiIuRCUtyCwcuIRC95FfP0ZB3WvfDeNxJChEAChNqmCMDE4iFvZhGuze8WqkJuIVdte+lyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-freebsd-x64": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.3.4.tgz", - "integrity": "sha512-bjSPak/d+bcR95/pxHMRhnnpHc6MnrQcG6f5AjX15Esm4JdrdQKPBmG1RybuK0WKSyD5wgVhkAGc/QQUom9l8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.3.4.tgz", - "integrity": "sha512-/1HnUL7jhH0S7PxJqf6R1pk3QlAU22GY89EQV9fd+RDUtp7IyzaTlkebijTIqfxlSjC4OO3bPizaxEaxdd3uKQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-linux-arm64-gnu": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.3.4.tgz", - "integrity": "sha512-g/2IaB2bZTKaBNPEf9LxtIXb1XHdhh3VO9PnePIrwkkixPMLN0dTxT5Sttt75lvLP3EU1AUR5w3Aaz2Q1mYtWA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-linux-arm64-musl": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.3.4.tgz", - "integrity": "sha512-MgfKLoEF6I1cCS+0ooFLEjJSSVdCYyCT9Q96IHRJntAEL8u/0GR2OUoBoLC+q1lnbIkJr/uqTJxA2Jh+sJTIbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-linux-x64-musl": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.3.4.tgz", - "integrity": "sha512-qIJKJCYFRLVSALsvg3avjReOjuYk91Q0hFXMJ2KaEM1Y3tdzcFN0fKBiaHexgbFIUk8zJuS4dJObTqSYMXowbg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/nx/node_modules/@nx/nx-win32-arm64-msvc": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.3.4.tgz", - "integrity": "sha512-UxC8mRkFTPdZbKFprZkiBqVw8624xU38kI0xyooxKlFpt5lccTBwJ0B7+R8p1RoWyvh2DSyFI9VvfD7lczg1lA==", - "cpu": [ - "arm64" - ], + "node_modules/nx/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/nx/node_modules/@nx/nx-win32-x64-msvc": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.3.4.tgz", - "integrity": "sha512-/RqEjNU9hxIBxRLafCNKoH3SaB2FShf+1ZnIYCdAoCZBxLJebDpnhiyrVs0lPnMj9248JbizEMdJj1+bs/bXig==", - "cpu": [ - "x64" - ], + "node_modules/nx/node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "ansi-colors": "^4.1.1" + }, "engines": { - "node": ">= 10" + "node": ">=8.6" } }, - "node_modules/nx/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/nx/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/nx/node_modules/minimatch": { @@ -21374,10 +21026,13 @@ } }, "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==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -21392,14 +21047,16 @@ } }, "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==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -21477,12 +21134,13 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -21635,6 +21293,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ora/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -21653,6 +21327,23 @@ "node": ">=0.10.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -21667,7 +21358,6 @@ "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", "dev": true, - "license": "MIT", "dependencies": { "p-timeout": "^3.1.0" }, @@ -21829,6 +21519,12 @@ "node": ">=8" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "node_modules/package-json/node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -22111,23 +21807,21 @@ } }, "node_modules/pacote/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -22142,9 +21836,9 @@ } }, "node_modules/pacote/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -22175,9 +21869,9 @@ } }, "node_modules/pacote/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -22338,9 +22032,9 @@ "dev": true }, "node_modules/parse-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.1.tgz", + "integrity": "sha512-6ReLMptznuuOEzLoGEa+I1oWRSj2Zna5jLWC+l6zlfAI4dbbSaIES29ThzuPkbhNahT65dWzfoZEO6cfJw2Ksg==", "dev": true, "dependencies": { "protocols": "^2.0.0" @@ -22356,12 +22050,12 @@ } }, "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==", "dev": true, "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -22469,13 +22163,10 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "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/path-scurry/node_modules/minipass": { "version": "7.1.2", @@ -22487,9 +22178,9 @@ } }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, "node_modules/path-type": { @@ -22533,18 +22224,18 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -22672,33 +22363,33 @@ } }, "node_modules/playwright": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", - "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz", + "integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==", "dev": true, "dependencies": { - "playwright-core": "1.44.1" + "playwright-core": "1.50.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz", - "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==", + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz", + "integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==", "dev": true, "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { @@ -22813,18 +22504,18 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { @@ -22841,9 +22532,9 @@ } ], "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -22881,13 +22572,13 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "dev": true, "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -22898,12 +22589,12 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -22928,9 +22619,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -23112,9 +22803,9 @@ } }, "node_modules/protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "dev": true }, "node_modules/proxy-from-env": { @@ -23130,15 +22821,21 @@ "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 + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "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==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, "dependencies": { "end-of-stream": "^1.1.0", @@ -23206,6 +22903,12 @@ } } }, + "node_modules/puppeteer-core/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/puppeteer-core/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -23244,9 +22947,9 @@ } }, "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz", + "integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==", "dev": true, "funding": [ { @@ -23263,6 +22966,7 @@ "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", @@ -23270,12 +22974,12 @@ } }, "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -23470,31 +23174,29 @@ } }, "node_modules/read-package-json/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/read-package-json/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", + "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", "dev": true, "dependencies": { "lru-cache": "^7.5.1" @@ -23522,9 +23224,9 @@ } }, "node_modules/read-package-json/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -23796,6 +23498,18 @@ "node": ">=8.10.0" } }, + "node_modules/readdirp/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/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -23818,6 +23532,28 @@ "node": ">=6" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -23825,9 +23561,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -23852,15 +23588,17 @@ } }, "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==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -23882,15 +23620,15 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -23922,25 +23660,34 @@ "node": ">=8" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/relateurl": { @@ -24063,18 +23810,21 @@ "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==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -24212,9 +23962,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rimraf": { @@ -24287,9 +24037,9 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -24326,10 +24076,22 @@ "rollup": "^2.0.0" } }, + "node_modules/rollup-plugin-terser/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/rollup-plugin-terser/node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -24406,6 +24168,18 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, + "node_modules/rollup-plugin-workbox/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/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -24439,23 +24213,33 @@ } }, "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "dependencies": { - "tslib": "^2.1.0" + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" } }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "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==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -24471,15 +24255,31 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -24501,9 +24301,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -24598,6 +24398,20 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^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", @@ -24644,36 +24458,92 @@ } }, "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==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shiki": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", - "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz", + "integrity": "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==", "dev": true, "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -24782,23 +24652,21 @@ } }, "node_modules/sigstore/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -24848,9 +24716,9 @@ } }, "node_modules/sigstore/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -25135,31 +25003,17 @@ } }, "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=8" } }, "node_modules/smart-buffer": { @@ -25448,6 +25302,20 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/snowpack/node_modules/fdir": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-5.3.0.tgz", + "integrity": "sha512-BtE53+jaa7nNHT+gPdfU6cFAXOJUWDs2b5GFox8dtl6zLXmfNf/N6im69b9nqNNwDyl27mpIWX8qR7AafWzSdQ==", + "dev": true, + "peerDependencies": { + "picomatch": "2.x" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/snowpack/node_modules/gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -25753,6 +25621,18 @@ "node": ">=10" } }, + "node_modules/snowpack/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/snowpack/node_modules/read-package-json-fast": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", @@ -25816,7 +25696,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", "dev": true, "hasInstallScript": true, "optional": true, @@ -25936,19 +25815,10 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/snowpack/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" - } - }, "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", "dev": true, "dependencies": { "ip-address": "^9.0.5", @@ -25995,9 +25865,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -26030,9 +25900,9 @@ "dev": true }, "node_modules/spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, "node_modules/spdx-correct": { @@ -26062,9 +25932,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", "dev": true }, "node_modules/split": { @@ -26314,15 +26184,6 @@ "node": ">= 0.6" } }, - "node_modules/stream-read-all": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", - "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -26353,9 +26214,9 @@ ] }, "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", "dev": true, "engines": { "node": ">=0.6.19" @@ -26402,48 +26263,31 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/string-width-cjs/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/string-width/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/string-width/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/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -26453,15 +26297,18 @@ } }, "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==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -26471,15 +26318,19 @@ } }, "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==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -26676,9 +26527,9 @@ "dev": true }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -26692,93 +26543,34 @@ } }, "node_modules/table-layout": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", - "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", "dev": true, "dependencies": { - "@75lb/deep-merge": "^1.1.1", "array-back": "^6.2.2", - "command-line-args": "^5.2.1", - "command-line-usage": "^7.0.0", - "stream-read-all": "^3.0.1", - "typical": "^7.1.1", "wordwrapjs": "^5.1.0" }, - "bin": { - "table-layout": "bin/cli.js" - }, - "engines": { - "node": ">=12.17" - } - }, - "node_modules/table-layout/node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/table-layout/node_modules/command-line-args/node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table-layout/node_modules/command-line-args/node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table-layout/node_modules/typical": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", - "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", - "dev": true, "engines": { "node": ">=12.17" } }, "node_modules/table/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/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/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -26805,8 +26597,7 @@ "node_modules/taffydb": { "version": "2.6.2", "resolved": "git+ssh://git@github.com/hegemonic/taffydb.git#e41b5e179e197bb85c5fb887b707672b1e5ca079", - "dev": true, - "license": "BSD-2-Clause" + "dev": true }, "node_modules/tar": { "version": "6.1.11", @@ -27014,15 +26805,6 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", @@ -27211,9 +26993,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -27334,23 +27116,21 @@ } }, "node_modules/tuf-js/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "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" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -27400,9 +27180,9 @@ } }, "node_modules/tuf-js/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -27525,9 +27305,9 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "engines": { "node": ">=4" @@ -27559,30 +27339,30 @@ } }, "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==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "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==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -27592,17 +27372,18 @@ } }, "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -27612,17 +27393,17 @@ } }, "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==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "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" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -27656,9 +27437,9 @@ } }, "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.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -27678,9 +27459,9 @@ } }, "node_modules/ua-parser-js": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", - "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", + "version": "1.0.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz", + "integrity": "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==", "dev": true, "funding": [ { @@ -27696,14 +27477,17 @@ "url": "https://github.com/sponsors/faisalman" } ], + "bin": { + "ua-parser-js": "script/cli.js" + }, "engines": { "node": "*" } }, "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==", + "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": { @@ -27714,15 +27498,18 @@ } }, "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -27751,9 +27538,9 @@ "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "engines": { "node": ">=4" @@ -27773,9 +27560,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, "engines": { "node": ">=4" @@ -27885,9 +27672,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { @@ -27904,8 +27691,8 @@ } ], "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -27954,6 +27741,12 @@ "node": ">=8" } }, + "node_modules/update-notifier/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, "node_modules/update-notifier/node_modules/is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -28169,6 +27962,18 @@ "node": ">=6.0" } }, + "node_modules/vm2/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -28176,9 +27981,9 @@ "dev": true }, "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", "dev": true }, "node_modules/walk-up-path": { @@ -28406,16 +28211,64 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "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" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -28437,15 +28290,16 @@ } }, "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==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -28456,17 +28310,60 @@ } }, "node_modules/wicg-inert": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz", - "integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.3.tgz", + "integrity": "sha512-5L0PKK7iP+0Q/jv2ccgmkz/pfXbumZtlEyWS/xnX+L+Og3f7WjL4+iEs18k4IuldOX3PgGpza3qGndL9xUBjCQ==" }, "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/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/wide-align/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/wide-align/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/wide-align/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/widest-line": { @@ -28669,15 +28566,15 @@ "dev": true }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -28720,6 +28617,18 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/workbox-build/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/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", @@ -28972,18 +28881,6 @@ "node": ">=8" } }, - "node_modules/workbox-cli/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/workbox-cli/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -28993,12 +28890,6 @@ "semver": "bin/semver" } }, - "node_modules/workbox-cli/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/workbox-cli/node_modules/type-fest": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", @@ -29319,7 +29210,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -29370,12 +29260,12 @@ "dev": true }, "node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, "engines": { - "node": ">= 14" + "node": ">= 6" } }, "node_modules/yamlparser": { @@ -29749,68 +29639,115 @@ "typescript": "4.3.5" } }, - "packages/addons/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "packages/addons/node_modules/typedoc": { + "version": "0.21.10", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.21.10.tgz", + "integrity": "sha512-Y0wYIehkjkPfsp3pv86fp3WPHUcOf8pnQUDLwG1PqSccUSqdsv7Pz1Gd5WrTJvXQB2wO1mKlZ8qW8qMiopKyjA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "glob": "^7.1.7", + "handlebars": "^4.7.7", + "lunr": "^2.3.9", + "marked": "^4.0.10", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shiki": "^0.9.8", + "typedoc-default-themes": "^0.12.10" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x" } }, - "packages/addons/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "packages/addons/node_modules/typedoc-plugin-markdown": { + "version": "3.10.4", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.4.tgz", + "integrity": "sha512-if9w7S9fXLg73AYi/EoRSEhTOZlg3I8mIP8YEmvzSE33VrNXC9/hA0nVcLEwFVJeQY7ay6z67I6kW0KIv7LjeA==", "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "handlebars": "^4.7.7" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "peerDependencies": { + "typedoc": ">=0.21.2" } }, - "packages/addons/node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "packages/addons/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">= 4" + "node": ">=4.2.0" } }, - "packages/addons/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, + "packages/core": { + "name": "@openscd/core", + "version": "0.1.4", + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@lit/localize": "^0.11.4", + "@open-wc/lit-helpers": "^0.5.1", + "lit": "^2.2.7" }, - "engines": { - "node": ">=10.10.0" + "devDependencies": { + "@custom-elements-manifest/analyzer": "^0.6.3", + "@lit/localize-tools": "^0.6.5", + "@open-wc/building-rollup": "^2.2.1", + "@open-wc/eslint-config": "^7.0.0", + "@open-wc/testing": "next", + "@rollup/plugin-typescript": "^9.0.2", + "@types/node": "^18.11.9", + "@typescript-eslint/eslint-plugin": "^5.30.7", + "@typescript-eslint/parser": "^5.30.7", + "@web/dev-server": "^0.1.32", + "@web/test-runner": "next", + "@web/test-runner-playwright": "^0.8.10", + "@web/test-runner-visual-regression": "^0.6.6", + "concurrently": "^7.3.0", + "es-dev-server": "^2.1.0", + "eslint": "^8.20.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-tsdoc": "^0.2.16", + "fast-check": "^3.1.1", + "gh-pages": "^4.0.0", + "husky": "^4.3.8", + "lint-staged": "^13.0.3", + "prettier": "^2.7.1", + "tsdoc": "^0.0.4", + "tslib": "^2.4.0", + "typedoc": "^0.23.8", + "typescript": "^4.7.4" } }, - "packages/addons/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "packages/core/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "packages/core/node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, - "packages/addons/node_modules/@open-wc/eslint-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", - "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", + "packages/core/node_modules/@open-wc/eslint-config": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-7.0.0.tgz", + "integrity": "sha512-iuWgs5XSPqb9zhdHIeKDSzepnjRyhoYSoS6RI+vyLMfVFRxZoqt0Yv4Q8xJ8yByXbJyakmvpukTyEKbcuIQ7Uw==", "dev": true, "dependencies": { "eslint": "^7.6.0", @@ -29818,7 +29755,7 @@ "eslint-plugin-html": "^6.0.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^1.0.1", + "eslint-plugin-lit-a11y": "^2.1.0", "eslint-plugin-no-only-tests": "^2.4.0", "eslint-plugin-wc": "^1.2.0" }, @@ -29827,89 +29764,127 @@ "eslint-plugin-html": "^6.0.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^1.0.1", + "eslint-plugin-lit-a11y": "^2.1.0", "eslint-plugin-no-only-tests": "^2.4.0", "eslint-plugin-wc": "^1.2.0" } }, - "packages/addons/node_modules/@open-wc/scoped-elements": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-1.3.7.tgz", - "integrity": "sha512-q/wKf4sXl7cr1kNfl8z6TLO2TrpXsFMCrfCD51sCEljltwYIXOmI6SnRXmWlnzG37A8AwHRpDXYmjPj2F4gPxA==", + "packages/core/node_modules/@open-wc/eslint-config/node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "dependencies": { - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-html": "^1.0.0" + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "packages/addons/node_modules/@open-wc/testing": { - "version": "2.5.33", - "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-2.5.33.tgz", - "integrity": "sha512-+EJNs0i+VV4nE+BrG70l2DNGXOZTSrluruaaU06HUSk57ZlKa+kIxWmkLxCOLlbgnQgrPrQWxbs3lgB1tIx/YA==", + "packages/core/node_modules/@open-wc/eslint-config/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "dependencies": { - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.3", - "@open-wc/testing-helpers": "^1.8.12", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/mocha": "^5.2.7", - "@types/sinon-chai": "^3.2.3", - "chai": "^4.2.0", - "chai-a11y-axe": "^1.3.1", - "chai-dom": "^1.8.1", - "mocha": "^6.2.2", - "sinon-chai": "^3.5.0" + "engines": { + "node": ">= 4" } }, - "packages/addons/node_modules/@open-wc/testing-helpers": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-1.8.12.tgz", - "integrity": "sha512-+4exEHYvnFqI1RGDDIKFHPZ7Ws5NK1epvEku3zLaOYN3zc+huX19SndNc5+X++v8A+quN/iXbHlh80ROyNaYDA==", + "packages/core/node_modules/@open-wc/eslint-config/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": { - "@open-wc/scoped-elements": "^1.2.4", - "lit-element": "^2.2.1", - "lit-html": "^1.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "packages/addons/node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "packages/addons/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==", - "dev": true + "packages/core/node_modules/@types/node": { + "version": "18.19.76", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.76.tgz", + "integrity": "sha512-yvR7Q9LdPz2vGpmpJX5LolrgRdWvB67MJKDPSgIIzpFbaf9a1j/f5DnLp5VDyHGMR0QZHlTr1afsD87QCXFHKw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, - "packages/addons/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "packages/core/node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -29917,26 +29892,26 @@ } } }, - "packages/addons/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "packages/core/node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -29944,52 +29919,52 @@ } } }, - "packages/addons/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "packages/core/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "packages/addons/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "packages/core/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "packages/addons/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "packages/core/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -30001,27 +29976,39 @@ } } }, - "packages/addons/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "packages/core/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "packages/addons/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "packages/core/node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/core/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -30030,7 +30017,58 @@ "node": ">=0.4.0" } }, - "packages/addons/node_modules/argparse": { + "packages/core/node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/core/node_modules/ansi-escapes/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" + } + }, + "packages/core/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "packages/core/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/core/node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", @@ -30039,73 +30077,133 @@ "sprintf-js": "~1.0.2" } }, - "packages/addons/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "packages/core/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "packages/core/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "packages/core/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=6.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "packages/core/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "packages/core/node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "packages/addons/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "packages/core/node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">= 12" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/concurrently": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", - "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", + "packages/core/node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "packages/core/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 + }, + "packages/core/node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "packages/core/node_modules/concurrently": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.6.0.tgz", + "integrity": "sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==", "dev": true, "dependencies": { "chalk": "^4.1.0", - "date-fns": "^2.16.1", + "date-fns": "^2.29.1", "lodash": "^4.17.21", - "rxjs": "^6.6.3", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", "spawn-command": "^0.0.2-1", "supports-color": "^8.1.0", "tree-kill": "^1.2.2", - "yargs": "^16.2.0" + "yargs": "^17.3.1" }, "bin": { - "concurrently": "bin/concurrently.js" + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" }, "engines": { - "node": ">=10.0.0" + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "packages/addons/node_modules/cosmiconfig": { + "packages/core/node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", @@ -30121,102 +30219,100 @@ "node": ">=10" } }, - "packages/addons/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "packages/core/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 + } + } + }, + "packages/core/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", "dev": true }, - "packages/addons/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "packages/core/node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "packages/addons/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" - } - }, - "packages/addons/node_modules/eslint-plugin-lit-a11y": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", - "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", + "packages/core/node_modules/eslint-plugin-lit-a11y": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-2.4.1.tgz", + "integrity": "sha512-UljRja/2cVrNtgnCDj5sCT3Larxda4mGqbsPhlksvECo0+KCD8EuUori/P6wFeFqk+pHlkIC3W200E5q85E3VQ==", "dev": true, "dependencies": { - "aria-query": "^4.2.2", + "aria-query": "^5.1.3", "axe-core": "^4.3.3", "axobject-query": "^2.2.0", "dom5": "^3.0.1", - "emoji-regex": "^9.2.0", - "eslint": "^7.6.0", + "emoji-regex": "^10.2.1", + "eslint-plugin-lit": "^1.6.0", "eslint-rule-extender": "0.0.1", - "intl-list-format": "^1.0.3", - "parse5": "^5.1.1", + "language-tags": "^1.0.5", + "parse5": "^7.1.2", "parse5-htmlparser2-tree-adapter": "^6.0.1", "requireindex": "~1.2.0" }, @@ -30224,7 +30320,7 @@ "eslint": ">= 5" } }, - "packages/addons/node_modules/eslint-utils": { + "packages/core/node_modules/eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", @@ -30239,7 +30335,7 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "packages/addons/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "packages/core/node_modules/eslint-utils/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==", @@ -30248,78 +30344,174 @@ "node": ">=4" } }, - "packages/addons/node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "packages/core/node_modules/eslint/node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "packages/addons/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "packages/core/node_modules/eslint/node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10.10.0" } }, - "packages/addons/node_modules/espree/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==", + "packages/core/node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "packages/addons/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "packages/core/node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/core/node_modules/eslint/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/core/node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "packages/core/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" + } + }, + "packages/core/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "packages/core/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.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" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "packages/addons/node_modules/fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", + "packages/core/node_modules/fast-check": { + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], "dependencies": { - "pure-rand": "^5.0.1" + "pure-rand": "^6.1.0" }, "engines": { "node": ">=8.0.0" + } + }, + "packages/core/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": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/globals": { + "packages/core/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", @@ -30334,88 +30526,132 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "packages/core/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "packages/core/node_modules/husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, "bin": { - "husky": "lib/bin.js" + "husky-run": "bin/run.js", + "husky-upgrade": "lib/upgrader/bin.js" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/typicode" + "type": "opencollective", + "url": "https://opencollective.com/husky" } }, - "packages/addons/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==", + "packages/core/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/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==", + "packages/core/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": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/lint-staged": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", - "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", + "packages/core/node_modules/lint-staged": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.3.0.tgz", + "integrity": "sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==", "dev": true, "dependencies": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" + "chalk": "5.3.0", + "commander": "11.0.0", + "debug": "4.3.4", + "execa": "7.2.0", + "lilconfig": "2.1.0", + "listr2": "6.6.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.1" }, "bin": { "lint-staged": "bin/lint-staged.js" }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + }, "funding": { "url": "https://opencollective.com/lint-staged" } }, - "packages/addons/node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "packages/core/node_modules/lint-staged/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" + } + }, + "packages/core/node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "packages/core/node_modules/listr2": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", + "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", "dev": true, "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^8.1.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" }, "peerDependencies": { "enquirer": ">= 2.3.0 < 3" @@ -30426,268 +30662,294 @@ } } }, - "packages/addons/node_modules/listr2/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 - }, - "packages/addons/node_modules/listr2/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "packages/core/node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", "dev": true, "dependencies": { - "tslib": "^2.1.0" + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "packages/addons/node_modules/pure-rand": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz", - "integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==", + "packages/core/node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, - "packages/addons/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "packages/core/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": { - "tslib": "^1.9.0" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "npm": ">=2.0.0" + "node": ">=8.6" } }, - "packages/addons/node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "packages/addons/node_modules/shiki": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz", - "integrity": "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==", + "packages/core/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, - "dependencies": { - "jsonc-parser": "^3.0.0", - "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "packages/core/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": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "packages/addons/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "packages/core/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 }, - "packages/addons/node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "packages/core/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": ">=0.6.19" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/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==", + "packages/core/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": { - "has-flag": "^4.0.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "packages/core/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" } }, - "packages/addons/node_modules/typedoc": { - "version": "0.21.10", + "packages/core/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "glob": "^7.1.7", - "handlebars": "^4.7.7", - "lunr": "^2.3.9", - "marked": "^4.0.10", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shiki": "^0.9.8", - "typedoc-default-themes": "^0.12.10" - }, - "bin": { - "typedoc": "bin/typedoc" - }, "engines": { - "node": ">= 12.10.0" + "node": ">=8.6" }, - "peerDependencies": { - "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "packages/addons/node_modules/typedoc-plugin-markdown": { - "version": "3.10.4", + "packages/core/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", "dev": true, - "license": "MIT", "dependencies": { - "handlebars": "^4.7.7" + "find-up": "^5.0.0" }, - "peerDependencies": { - "typedoc": ">=0.21.2" + "engines": { + "node": ">=10" } }, - "packages/addons/node_modules/typescript": { - "version": "4.3.5", + "packages/core/node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "packages/core/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=4.2.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", - "dev": true + "packages/core/node_modules/restore-cursor/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" + } }, - "packages/addons/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==", + "packages/core/node_modules/restore-cursor/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": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/addons/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "packages/core/node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, - "engines": { - "node": ">= 6" + "dependencies": { + "tslib": "^2.1.0" } }, - "packages/core": { - "name": "@openscd/core", - "version": "0.1.4", - "license": "Apache-2.0", + "packages/core/node_modules/shiki": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", + "dev": true, "dependencies": { - "@lit/localize": "^0.11.4", - "@open-wc/lit-helpers": "^0.5.1", - "lit": "^2.2.7" - }, - "devDependencies": { - "@custom-elements-manifest/analyzer": "^0.6.3", - "@lit/localize-tools": "^0.6.5", - "@open-wc/building-rollup": "^2.2.1", - "@open-wc/eslint-config": "^7.0.0", - "@open-wc/testing": "next", - "@rollup/plugin-typescript": "^9.0.2", - "@types/node": "^18.11.9", - "@typescript-eslint/eslint-plugin": "^5.30.7", - "@typescript-eslint/parser": "^5.30.7", - "@web/dev-server": "^0.1.32", - "@web/test-runner": "next", - "@web/test-runner-playwright": "^0.8.10", - "@web/test-runner-visual-regression": "^0.6.6", - "concurrently": "^7.3.0", - "es-dev-server": "^2.1.0", - "eslint": "^8.20.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-tsdoc": "^0.2.16", - "fast-check": "^3.1.1", - "gh-pages": "^4.0.0", - "husky": "^4.3.8", - "lint-staged": "^13.0.3", - "prettier": "^2.7.1", - "tsdoc": "^0.0.4", - "tslib": "^2.4.0", - "typedoc": "^0.23.8", - "typescript": "^4.7.4" + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" } }, - "packages/core/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "packages/core/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "packages/core/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "packages/core/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 + }, + "packages/core/node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "packages/core/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" + } + }, + "packages/core/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": { - "brace-expansion": "^2.0.1" + "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "packages/core/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "packages/core/node_modules/typedoc": { @@ -30711,6 +30973,30 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" } }, + "packages/core/node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "packages/core/node_modules/typedoc/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/core/node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -30724,20 +31010,108 @@ "node": ">=4.2.0" } }, - "packages/distribution": { - "name": "@openscd/distribution", - "version": "0.0.1", - "license": "Apache-2.0", + "packages/core/node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "packages/core/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { - "@openscd/addons": "*", - "@openscd/open-scd": "*", - "@openscd/plugins": "*" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, - "devDependencies": { - "@commitlint/cli": "^13.1.0", - "@commitlint/config-conventional": "^13.1.0", - "@open-wc/eslint-config": "^4.3.0", - "@open-wc/semantic-dom-diff": "^0.19.5", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "packages/core/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "packages/core/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "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" + } + }, + "packages/core/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "packages/core/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" + } + }, + "packages/core/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" + } + }, + "packages/distribution": { + "name": "@openscd/distribution", + "version": "0.0.1", + "license": "Apache-2.0", + "dependencies": { + "@openscd/addons": "*", + "@openscd/official-plugins": "*", + "@openscd/open-scd": "*" + }, + "devDependencies": { + "@commitlint/cli": "^13.1.0", + "@commitlint/config-conventional": "^13.1.0", + "@open-wc/eslint-config": "^4.3.0", + "@open-wc/semantic-dom-diff": "^0.19.5", "@open-wc/testing": "^2.5.33", "@snowpack/plugin-typescript": "^1.2.1", "@types/marked": "^2.0.4", @@ -30770,2394 +31144,141 @@ "workbox-cli": "^6.2.4" } }, - "packages/distribution/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "packages/distribution/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "packages/distribution/node_modules/typedoc": { + "version": "0.21.10", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.21.10.tgz", + "integrity": "sha512-Y0wYIehkjkPfsp3pv86fp3WPHUcOf8pnQUDLwG1PqSccUSqdsv7Pz1Gd5WrTJvXQB2wO1mKlZ8qW8qMiopKyjA==", "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "glob": "^7.1.7", + "handlebars": "^4.7.7", + "lunr": "^2.3.9", + "marked": "^4.0.10", + "minimatch": "^3.0.0", + "progress": "^2.0.3", + "shiki": "^0.9.8", + "typedoc-default-themes": "^0.12.10" + }, + "bin": { + "typedoc": "bin/typedoc" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x" } }, - "packages/distribution/node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "packages/distribution/node_modules/typedoc-plugin-markdown": { + "version": "3.10.4", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.4.tgz", + "integrity": "sha512-if9w7S9fXLg73AYi/EoRSEhTOZlg3I8mIP8YEmvzSE33VrNXC9/hA0nVcLEwFVJeQY7ay6z67I6kW0KIv7LjeA==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "handlebars": "^4.7.7" + }, + "peerDependencies": { + "typedoc": ">=0.21.2" } }, - "packages/distribution/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "packages/distribution/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=10.10.0" + "node": ">=4.2.0" } }, - "packages/distribution/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "packages/distribution/node_modules/@open-wc/eslint-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", - "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", - "dev": true, + "packages/openscd": { + "name": "@openscd/open-scd", + "version": "0.34.0", + "license": "Apache-2.0", "dependencies": { - "eslint": "^7.6.0", - "eslint-config-airbnb-base": "^14.0.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" + "@material/mwc-dialog": "0.22.1", + "@material/mwc-drawer": "0.22.1", + "@material/mwc-fab": "0.22.1", + "@material/mwc-formfield": "0.22.1", + "@material/mwc-icon": "0.22.1", + "@material/mwc-icon-button": "0.22.1", + "@material/mwc-icon-button-toggle": "0.22.1", + "@material/mwc-linear-progress": "0.22.1", + "@material/mwc-list": "0.22.1", + "@material/mwc-menu": "0.22.1", + "@material/mwc-select": "0.22.1", + "@material/mwc-snackbar": "0.22.1", + "@material/mwc-switch": "0.22.1", + "@material/mwc-tab": "0.22.1", + "@material/mwc-tab-bar": "0.22.1", + "@material/mwc-textarea": "0.22.1", + "@material/mwc-textfield": "0.22.1", + "@material/mwc-top-app-bar-fixed": "0.22.1", + "@openscd/core": "*", + "@openscd/xml": "*", + "ace-custom-element": "^1.6.5", + "lit": "^2.2.7", + "lit-translate": "^1.2.1", + "marked": "^4.0.10", + "panzoom": "^9.4.2" }, - "peerDependencies": { - "@babel/eslint-plugin": "^7.6.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" + "devDependencies": { + "@commitlint/cli": "^13.1.0", + "@commitlint/config-conventional": "^13.1.0", + "@open-wc/eslint-config": "^4.3.0", + "@open-wc/semantic-dom-diff": "^0.19.5", + "@open-wc/testing": "^2.5.33", + "@snowpack/plugin-typescript": "^1.2.1", + "@types/marked": "^2.0.4", + "@types/node": "^16.6.1", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", + "@web/dev-server-esbuild": "^0.2.16", + "@web/test-runner": "^0.13.22", + "@web/test-runner-playwright": "^0.11.0", + "concurrently": "^6.2.1", + "deepmerge": "^4.2.2", + "es-dev-server": "^2.1.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-babel": "^5.3.1", + "eslint-plugin-tsdoc": "^0.2.14", + "fast-check": "^2.19.0", + "husky": "^7.0.1", + "lint-staged": "^11.1.2", + "prettier": "^2.3.2", + "sinon": "^17.0.1", + "snowpack": "3.8.6", + "source-map": "^0.7.4", + "standard-version": "^9.3.1", + "tslib": "^2.3.1", + "typedoc": "^0.23.8", + "typedoc-plugin-markdown": "3.12.0", + "typescript": "^4.7.4", + "web-component-analyzer": "^1.1.6", + "workbox-cli": "^6.2.4" } }, - "packages/distribution/node_modules/@open-wc/scoped-elements": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-1.3.7.tgz", - "integrity": "sha512-q/wKf4sXl7cr1kNfl8z6TLO2TrpXsFMCrfCD51sCEljltwYIXOmI6SnRXmWlnzG37A8AwHRpDXYmjPj2F4gPxA==", + "packages/openscd/node_modules/@web/browser-logs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.1.tgz", + "integrity": "sha512-ypmMG+72ERm+LvP+loj9A64MTXvWMXHUOu773cPO4L1SV/VWg6xA9Pv7vkvkXQX+ItJtCJt+KQ+U6ui2HhSFUw==", "dev": true, "dependencies": { - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-html": "^1.0.0" + "errorstacks": "^2.4.1" + }, + "engines": { + "node": ">=18.0.0" } }, - "packages/distribution/node_modules/@open-wc/testing": { - "version": "2.5.33", - "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-2.5.33.tgz", - "integrity": "sha512-+EJNs0i+VV4nE+BrG70l2DNGXOZTSrluruaaU06HUSk57ZlKa+kIxWmkLxCOLlbgnQgrPrQWxbs3lgB1tIx/YA==", + "packages/openscd/node_modules/@web/dev-server-core": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.5.tgz", + "integrity": "sha512-Da65zsiN6iZPMRuj4Oa6YPwvsmZmo5gtPWhW2lx3GTUf5CAEapjVpZVlUXnKPL7M7zRuk72jSsIl8lo+XpTCtw==", "dev": true, - "dependencies": { - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.3", - "@open-wc/testing-helpers": "^1.8.12", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/mocha": "^5.2.7", - "@types/sinon-chai": "^3.2.3", - "chai": "^4.2.0", - "chai-a11y-axe": "^1.3.1", - "chai-dom": "^1.8.1", - "mocha": "^6.2.2", - "sinon-chai": "^3.5.0" - } - }, - "packages/distribution/node_modules/@open-wc/testing-helpers": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-1.8.12.tgz", - "integrity": "sha512-+4exEHYvnFqI1RGDDIKFHPZ7Ws5NK1epvEku3zLaOYN3zc+huX19SndNc5+X++v8A+quN/iXbHlh80ROyNaYDA==", - "dev": true, - "dependencies": { - "@open-wc/scoped-elements": "^1.2.4", - "lit-element": "^2.2.1", - "lit-html": "^1.0.0" - } - }, - "packages/distribution/node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "packages/distribution/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==", - "dev": true - }, - "packages/distribution/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/distribution/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/distribution/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/distribution/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/distribution/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/distribution/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/distribution/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/distribution/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" - } - }, - "packages/distribution/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "packages/distribution/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/distribution/node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, - "packages/distribution/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "packages/distribution/node_modules/concurrently": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", - "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "bin": { - "concurrently": "bin/concurrently.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "packages/distribution/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" - } - }, - "packages/distribution/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "packages/distribution/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/distribution/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" - } - }, - "packages/distribution/node_modules/eslint-plugin-lit-a11y": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", - "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", - "dev": true, - "dependencies": { - "aria-query": "^4.2.2", - "axe-core": "^4.3.3", - "axobject-query": "^2.2.0", - "dom5": "^3.0.1", - "emoji-regex": "^9.2.0", - "eslint": "^7.6.0", - "eslint-rule-extender": "0.0.1", - "intl-list-format": "^1.0.3", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "requireindex": "~1.2.0" - }, - "peerDependencies": { - "eslint": ">= 5" - } - }, - "packages/distribution/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "packages/distribution/node_modules/eslint-utils/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" - } - }, - "packages/distribution/node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "packages/distribution/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/distribution/node_modules/espree/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" - } - }, - "packages/distribution/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/sindresorhus/execa?sponsor=1" - } - }, - "packages/distribution/node_modules/fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", - "dev": true, - "dependencies": { - "pure-rand": "^5.0.1" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "packages/distribution/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/distribution/node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "packages/distribution/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" - } - }, - "packages/distribution/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" - } - }, - "packages/distribution/node_modules/lint-staged": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", - "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", - "dev": true, - "dependencies": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "packages/distribution/node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "packages/distribution/node_modules/listr2/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 - }, - "packages/distribution/node_modules/listr2/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/distribution/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "packages/distribution/node_modules/pure-rand": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz", - "integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "packages/distribution/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "packages/distribution/node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "packages/distribution/node_modules/shiki": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz", - "integrity": "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.0.0", - "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" - } - }, - "packages/distribution/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/distribution/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 - }, - "packages/distribution/node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "packages/distribution/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" - } - }, - "packages/distribution/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/distribution/node_modules/typedoc": { - "version": "0.21.10", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.21.10.tgz", - "integrity": "sha512-Y0wYIehkjkPfsp3pv86fp3WPHUcOf8pnQUDLwG1PqSccUSqdsv7Pz1Gd5WrTJvXQB2wO1mKlZ8qW8qMiopKyjA==", - "dev": true, - "dependencies": { - "glob": "^7.1.7", - "handlebars": "^4.7.7", - "lunr": "^2.3.9", - "marked": "^4.0.10", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shiki": "^0.9.8", - "typedoc-default-themes": "^0.12.10" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 12.10.0" - }, - "peerDependencies": { - "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x" - } - }, - "packages/distribution/node_modules/typedoc-plugin-markdown": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.4.tgz", - "integrity": "sha512-if9w7S9fXLg73AYi/EoRSEhTOZlg3I8mIP8YEmvzSE33VrNXC9/hA0nVcLEwFVJeQY7ay6z67I6kW0KIv7LjeA==", - "dev": true, - "dependencies": { - "handlebars": "^4.7.7" - }, - "peerDependencies": { - "typedoc": ">=0.21.2" - } - }, - "packages/distribution/node_modules/typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "packages/distribution/node_modules/vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", - "dev": true - }, - "packages/distribution/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" - } - }, - "packages/distribution/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" - } - }, - "packages/openscd": { - "name": "@openscd/open-scd", - "version": "0.34.0", - "license": "Apache-2.0", - "dependencies": { - "@material/mwc-dialog": "0.22.1", - "@material/mwc-drawer": "0.22.1", - "@material/mwc-fab": "0.22.1", - "@material/mwc-formfield": "0.22.1", - "@material/mwc-icon": "0.22.1", - "@material/mwc-icon-button": "0.22.1", - "@material/mwc-icon-button-toggle": "0.22.1", - "@material/mwc-linear-progress": "0.22.1", - "@material/mwc-list": "0.22.1", - "@material/mwc-menu": "0.22.1", - "@material/mwc-select": "0.22.1", - "@material/mwc-snackbar": "0.22.1", - "@material/mwc-switch": "0.22.1", - "@material/mwc-tab": "0.22.1", - "@material/mwc-tab-bar": "0.22.1", - "@material/mwc-textarea": "0.22.1", - "@material/mwc-textfield": "0.22.1", - "@material/mwc-top-app-bar-fixed": "0.22.1", - "@openscd/core": "*", - "@openscd/xml": "*", - "ace-custom-element": "^1.6.5", - "lit": "^2.2.7", - "lit-translate": "^1.2.1", - "marked": "^4.0.10", - "panzoom": "^9.4.2" - }, - "devDependencies": { - "@commitlint/cli": "^13.1.0", - "@commitlint/config-conventional": "^13.1.0", - "@open-wc/eslint-config": "^4.3.0", - "@open-wc/semantic-dom-diff": "^0.19.5", - "@open-wc/testing": "^2.5.33", - "@snowpack/plugin-typescript": "^1.2.1", - "@types/marked": "^2.0.4", - "@types/node": "^16.6.1", - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.2", - "@web/dev-server-esbuild": "^0.2.16", - "@web/dev-server-import-maps": "^0.2.1", - "@web/test-runner": "^0.13.22", - "@web/test-runner-playwright": "^0.11.0", - "concurrently": "^6.2.1", - "deepmerge": "^4.2.2", - "es-dev-server": "^2.1.0", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-tsdoc": "^0.2.14", - "fast-check": "^2.19.0", - "husky": "^7.0.1", - "lint-staged": "^11.1.2", - "prettier": "^2.3.2", - "sinon": "^17.0.1", - "snowpack": "3.8.6", - "source-map": "^0.7.4", - "standard-version": "^9.3.1", - "tslib": "^2.3.1", - "typedoc": "^0.23.8", - "typedoc-plugin-markdown": "3.12.0", - "typescript": "^4.7.4", - "web-component-analyzer": "^1.1.6", - "workbox-cli": "^6.2.4" - } - }, - "packages/openscd/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "packages/openscd/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/openscd/node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "packages/openscd/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "packages/openscd/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "packages/openscd/node_modules/@open-wc/eslint-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", - "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", - "dev": true, - "dependencies": { - "eslint": "^7.6.0", - "eslint-config-airbnb-base": "^14.0.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" - }, - "peerDependencies": { - "@babel/eslint-plugin": "^7.6.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" - } - }, - "packages/openscd/node_modules/@open-wc/scoped-elements": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-1.3.7.tgz", - "integrity": "sha512-q/wKf4sXl7cr1kNfl8z6TLO2TrpXsFMCrfCD51sCEljltwYIXOmI6SnRXmWlnzG37A8AwHRpDXYmjPj2F4gPxA==", - "dev": true, - "dependencies": { - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-html": "^1.0.0" - } - }, - "packages/openscd/node_modules/@open-wc/testing": { - "version": "2.5.33", - "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-2.5.33.tgz", - "integrity": "sha512-+EJNs0i+VV4nE+BrG70l2DNGXOZTSrluruaaU06HUSk57ZlKa+kIxWmkLxCOLlbgnQgrPrQWxbs3lgB1tIx/YA==", - "dev": true, - "dependencies": { - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.3", - "@open-wc/testing-helpers": "^1.8.12", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/mocha": "^5.2.7", - "@types/sinon-chai": "^3.2.3", - "chai": "^4.2.0", - "chai-a11y-axe": "^1.3.1", - "chai-dom": "^1.8.1", - "mocha": "^6.2.2", - "sinon-chai": "^3.5.0" - } - }, - "packages/openscd/node_modules/@open-wc/testing-helpers": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-1.8.12.tgz", - "integrity": "sha512-+4exEHYvnFqI1RGDDIKFHPZ7Ws5NK1epvEku3zLaOYN3zc+huX19SndNc5+X++v8A+quN/iXbHlh80ROyNaYDA==", - "dev": true, - "dependencies": { - "@open-wc/scoped-elements": "^1.2.4", - "lit-element": "^2.2.1", - "lit-html": "^1.0.0" - } - }, - "packages/openscd/node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "packages/openscd/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==", - "dev": true - }, - "packages/openscd/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/openscd/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/openscd/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/openscd/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/openscd/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/openscd/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/openscd/node_modules/@web/browser-logs": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", - "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "errorstacks": "^2.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/@web/dev-server-core": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.3.tgz", - "integrity": "sha512-GS+Ok6HiqNZOsw2oEv5V2OISZ2s/6icJodyGjUuD3RChr0G5HiESbKf2K8mZV4shTz9sRC9KSQf8qvno2gPKrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/koa": "^2.11.6", - "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.1.0", - "chokidar": "^4.0.1", - "clone": "^2.1.2", - "es-module-lexer": "^1.0.0", - "get-stream": "^6.0.0", - "is-stream": "^2.0.0", - "isbinaryfile": "^5.0.0", - "koa": "^2.13.0", - "koa-etag": "^4.0.0", - "koa-send": "^5.0.1", - "koa-static": "^5.0.0", - "lru-cache": "^8.0.4", - "mime-types": "^2.1.27", - "parse5": "^6.0.1", - "picomatch": "^2.2.2", - "ws": "^7.5.10" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/@web/dev-server-core/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "packages/openscd/node_modules/@web/parse5-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", - "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse5": "^6.0.1", - "parse5": "^6.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/@web/parse5-utils/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "packages/openscd/node_modules/@web/test-runner-core": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", - "integrity": "sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.11", - "@types/babel__code-frame": "^7.0.2", - "@types/co-body": "^6.1.0", - "@types/convert-source-map": "^2.0.0", - "@types/debounce": "^1.2.0", - "@types/istanbul-lib-coverage": "^2.0.3", - "@types/istanbul-reports": "^3.0.0", - "@web/browser-logs": "^0.4.0", - "@web/dev-server-core": "^0.7.3", - "chokidar": "^4.0.1", - "cli-cursor": "^3.1.0", - "co-body": "^6.1.0", - "convert-source-map": "^2.0.0", - "debounce": "^1.2.0", - "dependency-graph": "^0.11.0", - "globby": "^11.0.1", - "internal-ip": "^6.2.0", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.0.2", - "log-update": "^4.0.0", - "nanocolors": "^0.2.1", - "nanoid": "^3.1.25", - "open": "^8.0.2", - "picomatch": "^2.2.2", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/@web/test-runner-coverage-v8": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", - "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@web/test-runner-core": "^0.13.0", - "istanbul-lib-coverage": "^3.0.0", - "lru-cache": "^8.0.4", - "picomatch": "^2.2.2", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/@web/test-runner-playwright": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", - "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@web/test-runner-core": "^0.13.0", - "@web/test-runner-coverage-v8": "^0.8.0", - "playwright": "^1.22.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/openscd/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "packages/openscd/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "packages/openscd/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "packages/openscd/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/openscd/node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, - "packages/openscd/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "packages/openscd/node_modules/concurrently": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", - "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "bin": { - "concurrently": "bin/concurrently.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "packages/openscd/node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true, - "license": "MIT" - }, - "packages/openscd/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "packages/openscd/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" - } - }, - "packages/openscd/node_modules/eslint-plugin-lit-a11y": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", - "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", - "dev": true, - "dependencies": { - "aria-query": "^4.2.2", - "axe-core": "^4.3.3", - "axobject-query": "^2.2.0", - "dom5": "^3.0.1", - "emoji-regex": "^9.2.0", - "eslint": "^7.6.0", - "eslint-rule-extender": "0.0.1", - "intl-list-format": "^1.0.3", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "requireindex": "~1.2.0" - }, - "peerDependencies": { - "eslint": ">= 5" - } - }, - "packages/openscd/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "packages/openscd/node_modules/eslint-utils/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" - } - }, - "packages/openscd/node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "packages/openscd/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/openscd/node_modules/espree/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" - } - }, - "packages/openscd/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/sindresorhus/execa?sponsor=1" - } - }, - "packages/openscd/node_modules/fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", - "dev": true, - "dependencies": { - "pure-rand": "^5.0.1" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "packages/openscd/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/openscd/node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/node_modules/lint-staged": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", - "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", - "dev": true, - "dependencies": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "packages/openscd/node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "packages/openscd/node_modules/listr2/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 - }, - "packages/openscd/node_modules/listr2/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/openscd/node_modules/lru-cache": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16.14" - } - }, - "packages/openscd/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "packages/openscd/node_modules/pure-rand": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz", - "integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "packages/openscd/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "packages/openscd/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "packages/openscd/node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "packages/openscd/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/openscd/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 - }, - "packages/openscd/node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/openscd/node_modules/typedoc": { - "version": "0.23.28", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", - "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", - "dev": true, - "dependencies": { - "lunr": "^2.3.9", - "marked": "^4.2.12", - "minimatch": "^7.1.3", - "shiki": "^0.14.1" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 14.14" - }, - "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" - } - }, - "packages/openscd/node_modules/typedoc-plugin-markdown": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.12.0.tgz", - "integrity": "sha512-yKl7/KWD8nP6Ot6OzMLLc8wBzN3CmkBoI/YQzxT62a9xmDgxyeTxGbHbkUoSzhKFqMI3SR0AqV6prAhVKbYnxw==", - "dev": true, - "dependencies": { - "handlebars": "^4.7.7" - }, - "peerDependencies": { - "typedoc": ">=0.22.0" - } - }, - "packages/openscd/node_modules/typedoc/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/openscd/node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "packages/openscd/node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "packages/openscd/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" - } - }, - "packages/openscd/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" - } - }, - "packages/plugins": { - "name": "@openscd/plugins", - "version": "0.0.1", - "license": "Apache-2.0", - "dependencies": { - "@material/mwc-dialog": "0.22.1", - "@material/mwc-fab": "0.22.1", - "@material/mwc-formfield": "0.22.1", - "@material/mwc-icon": "0.22.1", - "@material/mwc-icon-button": "0.22.1", - "@material/mwc-icon-button-toggle": "0.22.1", - "@material/mwc-list": "0.22.1", - "@material/mwc-menu": "0.22.1", - "@material/mwc-select": "0.22.1", - "@material/mwc-switch": "0.22.1", - "@material/mwc-textarea": "0.22.1", - "@material/mwc-textfield": "0.22.1", - "@openscd/core": "*", - "@openscd/open-scd": "*", - "@openscd/wizards": "*", - "@openscd/xml": "*", - "lit": "^2.2.7", - "lit-translate": "^1.2.1", - "marked": "^4.0.10", - "panzoom": "^9.4.2" - }, - "devDependencies": { - "@commitlint/cli": "^13.1.0", - "@commitlint/config-conventional": "^13.1.0", - "@open-wc/eslint-config": "^4.3.0", - "@open-wc/semantic-dom-diff": "^0.19.5", - "@open-wc/testing": "^2.5.33", - "@snowpack/plugin-typescript": "^1.2.1", - "@types/marked": "^2.0.4", - "@types/node": "^16.6.1", - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.2", - "@web/dev-server-esbuild": "^0.2.16", - "@web/test-runner": "^0.13.22", - "@web/test-runner-playwright": "^0.11.0", - "concurrently": "^6.2.1", - "deepmerge": "^4.2.2", - "es-dev-server": "^2.1.0", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-tsdoc": "^0.2.14", - "fast-check": "^2.19.0", - "husky": "^7.0.1", - "lint-staged": "^11.1.2", - "prettier": "^2.3.2", - "sinon": "^17.0.1", - "snowpack": "3.8.6", - "source-map": "^0.7.4", - "standard-version": "^9.3.1", - "tslib": "^2.3.1", - "typedoc": "^0.23.8", - "typedoc-plugin-markdown": "3.12.0", - "typescript": "^4.7.4", - "web-component-analyzer": "^1.1.6", - "workbox-cli": "^6.2.4" - } - }, - "packages/plugins/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "packages/plugins/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "packages/plugins/node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "packages/plugins/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "packages/plugins/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "packages/plugins/node_modules/@open-wc/eslint-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", - "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", - "dev": true, - "dependencies": { - "eslint": "^7.6.0", - "eslint-config-airbnb-base": "^14.0.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" - }, - "peerDependencies": { - "@babel/eslint-plugin": "^7.6.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" - } - }, - "packages/plugins/node_modules/@open-wc/scoped-elements": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-1.3.7.tgz", - "integrity": "sha512-q/wKf4sXl7cr1kNfl8z6TLO2TrpXsFMCrfCD51sCEljltwYIXOmI6SnRXmWlnzG37A8AwHRpDXYmjPj2F4gPxA==", - "dev": true, - "dependencies": { - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-html": "^1.0.0" - } - }, - "packages/plugins/node_modules/@open-wc/testing": { - "version": "2.5.33", - "resolved": "https://registry.npmjs.org/@open-wc/testing/-/testing-2.5.33.tgz", - "integrity": "sha512-+EJNs0i+VV4nE+BrG70l2DNGXOZTSrluruaaU06HUSk57ZlKa+kIxWmkLxCOLlbgnQgrPrQWxbs3lgB1tIx/YA==", - "dev": true, - "dependencies": { - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.3", - "@open-wc/testing-helpers": "^1.8.12", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/mocha": "^5.2.7", - "@types/sinon-chai": "^3.2.3", - "chai": "^4.2.0", - "chai-a11y-axe": "^1.3.1", - "chai-dom": "^1.8.1", - "mocha": "^6.2.2", - "sinon-chai": "^3.5.0" - } - }, - "packages/plugins/node_modules/@open-wc/testing-helpers": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/@open-wc/testing-helpers/-/testing-helpers-1.8.12.tgz", - "integrity": "sha512-+4exEHYvnFqI1RGDDIKFHPZ7Ws5NK1epvEku3zLaOYN3zc+huX19SndNc5+X++v8A+quN/iXbHlh80ROyNaYDA==", - "dev": true, - "dependencies": { - "@open-wc/scoped-elements": "^1.2.4", - "lit-element": "^2.2.1", - "lit-html": "^1.0.0" - } - }, - "packages/plugins/node_modules/@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", - "dev": true - }, - "packages/plugins/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==", - "dev": true - }, - "packages/plugins/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/plugins/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/plugins/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/plugins/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/plugins/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/plugins/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/plugins/node_modules/@web/browser-logs": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", - "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "errorstacks": "^2.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/plugins/node_modules/@web/dev-server-core": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.3.tgz", - "integrity": "sha512-GS+Ok6HiqNZOsw2oEv5V2OISZ2s/6icJodyGjUuD3RChr0G5HiESbKf2K8mZV4shTz9sRC9KSQf8qvno2gPKrQ==", - "dev": true, - "license": "MIT", "dependencies": { "@types/koa": "^2.11.6", "@types/ws": "^7.4.0", @@ -33182,19 +31303,11 @@ "node": ">=18.0.0" } }, - "packages/plugins/node_modules/@web/dev-server-core/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "packages/plugins/node_modules/@web/parse5-utils": { + "packages/openscd/node_modules/@web/parse5-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", "dev": true, - "license": "MIT", "dependencies": { "@types/parse5": "^6.0.1", "parse5": "^6.0.1" @@ -33203,19 +31316,11 @@ "node": ">=18.0.0" } }, - "packages/plugins/node_modules/@web/parse5-utils/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "packages/plugins/node_modules/@web/test-runner-core": { + "packages/openscd/node_modules/@web/test-runner-core": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", "integrity": "sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.11", "@types/babel__code-frame": "^7.0.2", @@ -33248,12 +31353,11 @@ "node": ">=18.0.0" } }, - "packages/plugins/node_modules/@web/test-runner-coverage-v8": { + "packages/openscd/node_modules/@web/test-runner-coverage-v8": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, - "license": "MIT", "dependencies": { "@web/test-runner-core": "^0.13.0", "istanbul-lib-coverage": "^3.0.0", @@ -33265,12 +31369,11 @@ "node": ">=18.0.0" } }, - "packages/plugins/node_modules/@web/test-runner-playwright": { + "packages/openscd/node_modules/@web/test-runner-playwright": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", "dev": true, - "license": "MIT", "dependencies": { "@web/test-runner-core": "^0.13.0", "@web/test-runner-coverage-v8": "^0.8.0", @@ -33280,41 +31383,7 @@ "node": ">=18.0.0" } }, - "packages/plugins/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/plugins/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" - } - }, - "packages/plugins/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "packages/plugins/node_modules/brace-expansion": { + "packages/openscd/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", @@ -33323,12 +31392,11 @@ "balanced-match": "^1.0.0" } }, - "packages/plugins/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "packages/openscd/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -33339,523 +31407,431 @@ "url": "https://paulmillr.com/funding/" } }, - "packages/plugins/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/plugins/node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "packages/openscd/node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true }, - "packages/plugins/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "packages/plugins/node_modules/concurrently": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", - "integrity": "sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==", + "packages/openscd/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "bin": { - "concurrently": "bin/concurrently.js" - }, "engines": { - "node": ">=10.0.0" + "node": ">=16.14" } }, - "packages/plugins/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "packages/openscd/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "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" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "packages/plugins/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "packages/openscd/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "packages/plugins/node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "packages/openscd/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "packages/plugins/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "packages/openscd/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 14.18.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "packages/openscd/node_modules/shiki": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" } }, - "packages/plugins/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "packages/openscd/node_modules/typedoc": { + "version": "0.23.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", + "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", "dev": true, "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" + "lunr": "^2.3.9", + "marked": "^4.2.12", + "minimatch": "^7.1.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 6" + "node": ">= 14.14" }, "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" } }, - "packages/plugins/node_modules/eslint-plugin-lit-a11y": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", - "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", + "packages/openscd/node_modules/typedoc-plugin-markdown": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.12.0.tgz", + "integrity": "sha512-yKl7/KWD8nP6Ot6OzMLLc8wBzN3CmkBoI/YQzxT62a9xmDgxyeTxGbHbkUoSzhKFqMI3SR0AqV6prAhVKbYnxw==", "dev": true, "dependencies": { - "aria-query": "^4.2.2", - "axe-core": "^4.3.3", - "axobject-query": "^2.2.0", - "dom5": "^3.0.1", - "emoji-regex": "^9.2.0", - "eslint": "^7.6.0", - "eslint-rule-extender": "0.0.1", - "intl-list-format": "^1.0.3", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "requireindex": "~1.2.0" + "handlebars": "^4.7.7" }, "peerDependencies": { - "eslint": ">= 5" + "typedoc": ">=0.22.0" } }, - "packages/plugins/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "packages/openscd/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=4.2.0" } }, - "packages/plugins/node_modules/eslint-utils/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==", + "packages/openscd/node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, "engines": { - "node": ">=4" + "node": ">=10.12.0" } }, - "packages/plugins/node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } + "packages/openscd/node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true }, - "packages/plugins/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, + "packages/oscd-official-plugins": { + "name": "@openscd/official-plugins", + "version": "0.0.1", + "license": "Apache-2.0", + "workspaces": [ + "./*", + "openscd/packages/*" + ], "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "@material/mwc-dialog": "0.22.1", + "@material/mwc-fab": "0.22.1", + "@material/mwc-formfield": "0.22.1", + "@material/mwc-icon": "0.22.1", + "@material/mwc-icon-button": "0.22.1", + "@material/mwc-icon-button-toggle": "0.22.1", + "@material/mwc-list": "0.22.1", + "@material/mwc-menu": "0.22.1", + "@material/mwc-select": "0.22.1", + "@material/mwc-switch": "0.22.1", + "@material/mwc-textarea": "0.22.1", + "@material/mwc-textfield": "0.22.1", + "@openscd/core": "*", + "@openscd/open-scd": "*", + "@openscd/wizards": "*", + "@openscd/xml": "*", + "lit": "^2.2.7", + "lit-translate": "^1.2.1", + "marked": "^4.0.10", + "panzoom": "^9.4.2" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "devDependencies": { + "@commitlint/cli": "^13.1.0", + "@commitlint/config-conventional": "^13.1.0", + "@open-wc/eslint-config": "^4.3.0", + "@open-wc/semantic-dom-diff": "^0.19.5", + "@open-wc/testing": "^2.5.33", + "@snowpack/plugin-typescript": "^1.2.1", + "@types/marked": "^2.0.4", + "@types/node": "^16.6.1", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", + "@web/dev-server-esbuild": "^0.2.16", + "@web/test-runner": "^0.13.22", + "@web/test-runner-playwright": "^0.11.0", + "concurrently": "^6.2.1", + "deepmerge": "^4.2.2", + "es-dev-server": "^2.1.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-babel": "^5.3.1", + "eslint-plugin-tsdoc": "^0.2.14", + "fast-check": "^2.19.0", + "husky": "^7.0.1", + "lint-staged": "^11.1.2", + "prettier": "^2.3.2", + "sinon": "^17.0.1", + "snowpack": "3.8.6", + "source-map": "^0.7.4", + "standard-version": "^9.3.1", + "tslib": "^2.3.1", + "typedoc": "^0.23.8", + "typedoc-plugin-markdown": "3.12.0", + "typescript": "^4.7.4", + "web-component-analyzer": "^1.1.6", + "workbox-cli": "^6.2.4" } }, - "packages/plugins/node_modules/espree/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==", + "packages/oscd-official-plugins/node_modules/@web/browser-logs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.1.tgz", + "integrity": "sha512-ypmMG+72ERm+LvP+loj9A64MTXvWMXHUOu773cPO4L1SV/VWg6xA9Pv7vkvkXQX+ItJtCJt+KQ+U6ui2HhSFUw==", "dev": true, + "dependencies": { + "errorstacks": "^2.4.1" + }, "engines": { - "node": ">=4" + "node": ">=18.0.0" } }, - "packages/plugins/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "packages/oscd-official-plugins/node_modules/@web/dev-server-core": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.5.tgz", + "integrity": "sha512-Da65zsiN6iZPMRuj4Oa6YPwvsmZmo5gtPWhW2lx3GTUf5CAEapjVpZVlUXnKPL7M7zRuk72jSsIl8lo+XpTCtw==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^4.0.1", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", "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" + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.5.10" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=18.0.0" } }, - "packages/plugins/node_modules/fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", + "packages/oscd-official-plugins/node_modules/@web/parse5-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", + "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", "dev": true, "dependencies": { - "pure-rand": "^5.0.1" + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" }, "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" + "node": ">=18.0.0" } }, - "packages/plugins/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "packages/oscd-official-plugins/node_modules/@web/test-runner-core": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.4.tgz", + "integrity": "sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/plugins/node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.3", + "chokidar": "^4.0.1", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "internal-ip": "^6.2.0", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" + "node": ">=18.0.0" } }, - "packages/plugins/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==", + "packages/oscd-official-plugins/node_modules/@web/test-runner-coverage-v8": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", + "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", "dev": true, + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "istanbul-lib-coverage": "^3.0.0", + "lru-cache": "^8.0.4", + "picomatch": "^2.2.2", + "v8-to-istanbul": "^9.0.1" + }, "engines": { - "node": ">=8" + "node": ">=18.0.0" } }, - "packages/plugins/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==", + "packages/oscd-official-plugins/node_modules/@web/test-runner-playwright": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", + "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", + "playwright": "^1.22.2" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=18.0.0" } }, - "packages/plugins/node_modules/lint-staged": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", - "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", + "packages/oscd-official-plugins/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" + "balanced-match": "^1.0.0" } }, - "packages/plugins/node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "packages/oscd-official-plugins/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" + "node": ">= 14.16.0" }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "packages/plugins/node_modules/listr2/node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "packages/oscd-official-plugins/node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true }, - "packages/plugins/node_modules/listr2/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "packages/plugins/node_modules/lru-cache": { + "packages/oscd-official-plugins/node_modules/lru-cache": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "dev": true, - "license": "ISC", "engines": { "node": ">=16.14" } }, - "packages/plugins/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "packages/plugins/node_modules/pure-rand": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz", - "integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "packages/plugins/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "packages/plugins/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "packages/oscd-official-plugins/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "dev": true, "dependencies": { - "tslib": "^1.9.0" + "brace-expansion": "^2.0.1" }, "engines": { - "npm": ">=2.0.0" - } - }, - "packages/plugins/node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "packages/plugins/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "packages/plugins/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "packages/oscd-official-plugins/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "packages/plugins/node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "packages/oscd-official-plugins/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": ">=0.6.19" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "packages/plugins/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==", + "packages/oscd-official-plugins/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "packages/plugins/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "packages/oscd-official-plugins/node_modules/shiki": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" } }, - "packages/plugins/node_modules/typedoc": { + "packages/oscd-official-plugins/node_modules/typedoc": { "version": "0.23.28", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", @@ -33876,7 +31852,7 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" } }, - "packages/plugins/node_modules/typedoc-plugin-markdown": { + "packages/oscd-official-plugins/node_modules/typedoc-plugin-markdown": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.12.0.tgz", "integrity": "sha512-yKl7/KWD8nP6Ot6OzMLLc8wBzN3CmkBoI/YQzxT62a9xmDgxyeTxGbHbkUoSzhKFqMI3SR0AqV6prAhVKbYnxw==", @@ -33888,75 +31864,39 @@ "typedoc": ">=0.22.0" } }, - "packages/plugins/node_modules/typedoc/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/plugins/node_modules/typescript": { + "packages/oscd-official-plugins/node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "packages/plugins/node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "packages/plugins/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" + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=4.2.0" } }, - "packages/plugins/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "packages/oscd-official-plugins/node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, "engines": { - "node": ">= 6" + "node": ">=10.12.0" } }, + "packages/oscd-official-plugins/node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "packages/wizards": { "name": "@openscd/wizards", "version": "0.0.1", @@ -33997,596 +31937,550 @@ "typescript": "^4.7.4" } }, - "packages/xml/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "packages/xml/node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "packages/xml/node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "type-fest": "^1.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@eslint/eslintrc/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==", + "packages/xml/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "packages/xml/node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "packages/xml/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "packages/xml/node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "packages/xml/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "balanced-match": "^1.0.0" } }, - "packages/xml/node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "packages/xml/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=10.10.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@humanwhocodes/config-array/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==", + "packages/xml/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "packages/xml/node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "*" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "packages/xml/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 }, - "packages/xml/node_modules/@open-wc/eslint-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@open-wc/eslint-config/-/eslint-config-4.3.0.tgz", - "integrity": "sha512-kCxFWQ1AR4meTmWJGnK36LJYqDJeFGjlj6n4vLjAW3/c1VUyYQKL90vrNKy/OHS9kTjc9dcH5D64myAbNx6r1w==", + "packages/xml/node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "packages/xml/node_modules/concurrently": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.6.0.tgz", + "integrity": "sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==", "dev": true, "dependencies": { - "eslint": "^7.6.0", - "eslint-config-airbnb-base": "^14.0.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.2.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" }, - "peerDependencies": { - "@babel/eslint-plugin": "^7.6.0", - "eslint-plugin-html": "^6.0.0", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-lit": "^1.3.0", - "eslint-plugin-lit-a11y": "^1.0.1", - "eslint-plugin-no-only-tests": "^2.4.0", - "eslint-plugin-wc": "^1.2.0" + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "packages/xml/node_modules/@open-wc/scoped-elements": { - "version": "1.3.7", + "packages/xml/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, - "license": "MIT", "dependencies": { - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-html": "^1.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "packages/xml/node_modules/@open-wc/testing": { - "version": "2.5.33", + "packages/xml/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "packages/xml/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", "dev": true, - "license": "MIT", "dependencies": { - "@open-wc/chai-dom-equals": "^0.12.36", - "@open-wc/semantic-dom-diff": "^0.19.3", - "@open-wc/testing-helpers": "^1.8.12", - "@types/chai": "^4.2.11", - "@types/chai-dom": "^0.0.9", - "@types/mocha": "^5.2.7", - "@types/sinon-chai": "^3.2.3", - "chai": "^4.2.0", - "chai-a11y-axe": "^1.3.1", - "chai-dom": "^1.8.1", - "mocha": "^6.2.2", - "sinon-chai": "^3.5.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "packages/xml/node_modules/@open-wc/testing-helpers": { - "version": "1.8.12", + "packages/xml/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, - "license": "MIT", - "dependencies": { - "@open-wc/scoped-elements": "^1.2.4", - "lit-element": "^2.2.1", - "lit-html": "^1.0.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@types/mocha": { - "version": "5.2.7", + "packages/xml/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, - "license": "MIT" - }, - "packages/xml/node_modules/@types/node": { - "version": "16.18.98", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.98.tgz", - "integrity": "sha512-fpiC20NvLpTLAzo3oVBKIqBGR6Fx/8oAK/SSf7G+fydnXMY1x4x9RZ6sBXhqKlCU21g2QapUsbLlhv3+a7wS+Q==", - "dev": true + "engines": { + "node": ">=14.18.0" + } }, - "packages/xml/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "packages/xml/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "packages/xml/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": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "packages/xml/node_modules/lint-staged": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.3.0.tgz", + "integrity": "sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "chalk": "5.3.0", + "commander": "11.0.0", + "debug": "4.3.4", + "execa": "7.2.0", + "lilconfig": "2.1.0", + "listr2": "6.6.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^16.14.0 || >=18.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/lint-staged" } }, - "packages/xml/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "packages/xml/node_modules/lint-staged/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": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "packages/xml/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "packages/xml/node_modules/listr2": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", + "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" }, "peerDependenciesMeta": { - "typescript": { + "enquirer": { "optional": true } } }, - "packages/xml/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "packages/xml/node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "packages/xml/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, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=0.4.0" + "node": ">=8.6" } }, - "packages/xml/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "packages/xml/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, - "dependencies": { - "sprintf-js": "~1.0.2" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "packages/xml/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "packages/xml/node_modules/brace-expansion": { - "version": "2.0.1", + "packages/xml/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 + }, + "packages/xml/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, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "packages/xml/node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "packages/xml/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": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "mimic-fn": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "packages/xml/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, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, "engines": { - "node": ">= 6" + "node": ">=12" }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/eslint-plugin-lit-a11y": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit-a11y/-/eslint-plugin-lit-a11y-1.1.0.tgz", - "integrity": "sha512-reJqT0UG/Y8OC2z7pfgm0ODK1D6o5TgQpGdlgN1ja0HjdREXLqFVoYiEv013oNx3kBhTUaLlic64rRNw+386xw==", + "packages/xml/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": { - "aria-query": "^4.2.2", - "axe-core": "^4.3.3", - "axobject-query": "^2.2.0", - "dom5": "^3.0.1", - "emoji-regex": "^9.2.0", - "eslint": "^7.6.0", - "eslint-rule-extender": "0.0.1", - "intl-list-format": "^1.0.3", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "requireindex": "~1.2.0" + "engines": { + "node": ">=8.6" }, - "peerDependencies": { - "eslint": ">= 5" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "packages/xml/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "packages/xml/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/eslint-utils/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==", + "packages/xml/node_modules/restore-cursor/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": ">=4" + "node": ">=6" } }, - "packages/xml/node_modules/eslint/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==", + "packages/xml/node_modules/restore-cursor/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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "packages/xml/node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "tslib": "^2.1.0" } }, - "packages/xml/node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "packages/xml/node_modules/shiki": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" } }, - "packages/xml/node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "packages/xml/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "packages/xml/node_modules/espree/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==", + "packages/xml/node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.6.19" } }, - "packages/xml/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "packages/xml/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "packages/xml/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==", + "packages/xml/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": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "engines": { + "node": ">=12" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/xml/node_modules/minimatch": { - "version": "7.4.6", + "packages/xml/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, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "packages/xml/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "packages/xml/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 - }, "packages/xml/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "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" @@ -34597,8 +32491,9 @@ }, "packages/xml/node_modules/typedoc": { "version": "0.23.28", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", + "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", "marked": "^4.2.12", @@ -34617,8 +32512,9 @@ }, "packages/xml/node_modules/typescript": { "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -34626,6 +32522,82 @@ "engines": { "node": ">=4.2.0" } + }, + "packages/xml/node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "packages/xml/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "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" + } + }, + "packages/xml/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "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" + } + }, + "packages/xml/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "packages/xml/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" + } + }, + "packages/xml/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" + } } } } diff --git a/packages/distribution/package.json b/packages/distribution/package.json index cf160d75d7..b28b81f3cc 100644 --- a/packages/distribution/package.json +++ b/packages/distribution/package.json @@ -22,7 +22,7 @@ "dependencies": { "@openscd/addons": "*", "@openscd/open-scd": "*", - "@openscd/plugins": "*" + "@openscd/official-plugins": "*" }, "scripts": { "clean": "rimraf build", diff --git a/packages/distribution/snowpack.config.mjs b/packages/distribution/snowpack.config.mjs index cbe594598d..fb27f15dcd 100644 --- a/packages/distribution/snowpack.config.mjs +++ b/packages/distribution/snowpack.config.mjs @@ -25,12 +25,12 @@ export default { workspaceRoot: '../../', mount: { './': '/', - '../plugins/': '/plugins/', + '../oscd-official-plugins/apps/plugins/': '/plugins/', '../openscd/': '/openscd/', }, alias: { '@openscd/open-scd': '../openscd/', - '@openscd/plugins': '../plugins/', + '@openscd/plugins': '../oscd-official-plugins/apps/plugins/', }, buildOptions: { baseUrl: process.env.PUBLIC_URL || '/', diff --git a/packages/oscd-official-plugins b/packages/oscd-official-plugins new file mode 160000 index 0000000000..8115e3d173 --- /dev/null +++ b/packages/oscd-official-plugins @@ -0,0 +1 @@ +Subproject commit 8115e3d17331373a5269b2b31e0d4cae7a2e581b diff --git a/packages/plugins/.eslintrc.cjs b/packages/plugins/.eslintrc.cjs deleted file mode 100644 index dc4fad8efe..0000000000 --- a/packages/plugins/.eslintrc.cjs +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-env node */ -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc', 'import', 'html'], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:import/errors', - 'plugin:import/warnings', - ], - rules: { - // disable the rule for all files - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - 'import/named': 'off', - 'import/no-unresolved': 'off', - 'import/extensions': ['error', 'always', { ignorePackages: true }], - 'import/no-duplicates': 'off', - 'no-duplicate-imports': 'off', - 'tsdoc/syntax': 'warn' - }, -}; diff --git a/packages/plugins/.gitignore b/packages/plugins/.gitignore deleted file mode 100644 index 2b34b601a7..0000000000 --- a/packages/plugins/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -## editors -/.idea -/.vscode - -## system files -.DS_Store - -## npm -node_modules/ -/npm-debug.log - -## testing -/coverage/ -/**/dist/*.snap.dev.js - -## docs -/doc/ - -# build -/_site/ -/build/ -/dist/ diff --git a/packages/plugins/.nojekyll b/packages/plugins/.nojekyll deleted file mode 100644 index afbfa3940c..0000000000 --- a/packages/plugins/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -snowpack placeholder diff --git a/packages/plugins/README.md b/packages/plugins/README.md deleted file mode 100644 index 2ab70bfdf8..0000000000 --- a/packages/plugins/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `OpenSCD Official Plug-ins` - -All the offical plug-ins are listed [here](https://github.com/openscd/open-scd/blob/main/docs/plug-ins.md) diff --git a/packages/plugins/package.json b/packages/plugins/package.json deleted file mode 100644 index 9e38d085dd..0000000000 --- a/packages/plugins/package.json +++ /dev/null @@ -1,166 +0,0 @@ -{ - "name": "@openscd/plugins", - "version": "0.0.1", - "repository": "https://github.com/openscd/open-scd.git", - "directory": "packages/plugins", - "description": "The official plug-ins of open-scd.", - "keywords": [ - "SCL", - "substation configuration", - "IEC", - "61850-6", - "SCD", - "editor" - ], - "author": "Open-SCD", - "license": "Apache-2.0", - "type": "module", - "private": true, - "dependencies": { - "@material/mwc-dialog": "0.22.1", - "@material/mwc-fab": "0.22.1", - "@material/mwc-formfield": "0.22.1", - "@material/mwc-icon": "0.22.1", - "@material/mwc-icon-button": "0.22.1", - "@material/mwc-icon-button-toggle": "0.22.1", - "@material/mwc-list": "0.22.1", - "@material/mwc-menu": "0.22.1", - "@material/mwc-select": "0.22.1", - "@material/mwc-switch": "0.22.1", - "@material/mwc-textarea": "0.22.1", - "@material/mwc-textfield": "0.22.1", - "@openscd/core": "*", - "@openscd/open-scd": "*", - "@openscd/wizards": "*", - "@openscd/xml": "*", - "lit": "^2.2.7", - "lit-translate": "^1.2.1", - "marked": "^4.0.10", - "panzoom": "^9.4.2" - }, - "scripts": { - "clean": "rimraf dist", - "lint:eslint": "eslint --ext .ts,.html . --ignore-path .gitignore", - "format:eslint": "eslint --ext .ts,.html . --fix --ignore-path .gitignore", - "lint:prettier": "prettier \"**/*.js\" \"**/*.ts\" --check --ignore-path .gitignore", - "format:prettier": "prettier \"**/*.js\" \"**/*.ts\" --write --ignore-path .gitignore", - "lint": "npm run lint:eslint && npm run lint:prettier", - "format": "npm run format:eslint && npm run format:prettier", - "test": "web-test-runner --coverage", - "test:snapshot": "web-test-runner --update-snapshots --coverage", - "test:manual": "web-test-runner --manual", - "test:watch": "web-test-runner --watch", - "test:unit": "web-test-runner --watch --group unit", - "test:integration": "web-test-runner --watch --group integration", - "doc:clean": "npx rimraf doc", - "doc:typedoc": "typedoc --plugin none --out doc --entryPointStrategy expand ./src", - "doc:wca": "wca src --outDir doc/components", - "doc": "npm run doc:clean && npm run doc:typedoc && npm run doc:wca", - "release": "standard-version", - "release:minor": "standard-version --release-as minor", - "release:patch": "standard-version --release-as patch", - "release:major": "standard-version --release-as major", - "build": "npm run doc && npm run bundle", - "bundle": "tsc" - }, - "devDependencies": { - "@commitlint/cli": "^13.1.0", - "@commitlint/config-conventional": "^13.1.0", - "@open-wc/eslint-config": "^4.3.0", - "@open-wc/semantic-dom-diff": "^0.19.5", - "@open-wc/testing": "^2.5.33", - "@snowpack/plugin-typescript": "^1.2.1", - "@types/marked": "^2.0.4", - "@types/node": "^16.6.1", - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.2", - "@web/dev-server-esbuild": "^0.2.16", - "@web/test-runner": "^0.13.22", - "@web/test-runner-playwright": "^0.11.0", - "concurrently": "^6.2.1", - "deepmerge": "^4.2.2", - "es-dev-server": "^2.1.0", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-tsdoc": "^0.2.14", - "fast-check": "^2.19.0", - "husky": "^7.0.1", - "lint-staged": "^11.1.2", - "prettier": "^2.3.2", - "sinon": "^17.0.1", - "snowpack": "3.8.6", - "source-map": "^0.7.4", - "standard-version": "^9.3.1", - "tslib": "^2.3.1", - "typedoc": "^0.23.8", - "typedoc-plugin-markdown": "3.12.0", - "typescript": "^4.7.4", - "web-component-analyzer": "^1.1.6", - "workbox-cli": "^6.2.4" - }, - "eslintConfig": { - "extends": [ - "@open-wc/eslint-config", - "eslint-config-prettier" - ] - }, - "prettier": { - "singleQuote": true, - "arrowParens": "avoid" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged", - "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" - } - }, - "lint-staged": { - "*.ts": [ - "eslint --fix", - "prettier --write" - ] - }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "standard-version": { - "types": [ - { - "type": "feat", - "section": "Features" - }, - { - "type": "fix", - "section": "Bug Fixes" - }, - { - "type": "chore", - "hidden": true - }, - { - "type": "docs", - "hidden": true - }, - { - "type": "style", - "hidden": true - }, - { - "type": "refactor", - "hidden": true - }, - { - "type": "perf", - "hidden": true - }, - { - "type": "test", - "hidden": true - } - ], - "commitUrlFormat": "https://github.com/openscd/open-scd/commits/{{hash}}" - } -} diff --git a/packages/plugins/project.json b/packages/plugins/project.json deleted file mode 100644 index b979aa4465..0000000000 --- a/packages/plugins/project.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@openscd/plugins", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "library", - "sourceRoot": "packages/plugins/src", - "targets": { - } - -} diff --git a/packages/plugins/public/js/worker.js b/packages/plugins/public/js/worker.js deleted file mode 100644 index 5ce38fed25..0000000000 --- a/packages/plugins/public/js/worker.js +++ /dev/null @@ -1,9 +0,0 @@ -importScripts('xmlvalidate.js'); - -onmessage = function(e) { - Module.ready.then(function(mod) { - if (e.data.name.toLowerCase().endsWith('.xsd')) - mod.init(e.data.content, e.data.name); - else mod.validate(e.data.content, e.data.name); - }); -}; diff --git a/packages/plugins/public/js/xmlvalidate.js b/packages/plugins/public/js/xmlvalidate.js deleted file mode 100644 index b4dc60d78f..0000000000 --- a/packages/plugins/public/js/xmlvalidate.js +++ /dev/null @@ -1 +0,0 @@ -var Module=typeof Module!=="undefined"?Module:{};Module["print"]=function(text){try{postMessage(JSON.parse(text.replace(/\\/g,"\\\\")))}catch(e){console.error(e);postMessage(text)}};Module["printErr"]=function(text){postMessage(text)};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var wasmTable;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":2147483648/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPreMain(cb){__ATMAIN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var wasmBinaryFile="xmlvalidate.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return Promise.resolve().then(getBinary)}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmTable=Module["asm"]["p"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd);if(size>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}__ATINIT__.push({func:function(){___wasm_call_ctors()}});var asmLibraryArg={"e":___sys_fcntl64,"g":___sys_getcwd,"i":___sys_ioctl,"j":___sys_open,"o":___sys_stat64,"l":_emscripten_memcpy_big,"m":_emscripten_resize_heap,"n":_environ_get,"f":_environ_sizes_get,"c":_fd_close,"h":_fd_read,"k":_fd_seek,"d":_fd_write,"a":wasmMemory,"b":_time};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["q"]).apply(null,arguments)};var _init=Module["_init"]=function(){return(_init=Module["_init"]=Module["asm"]["r"]).apply(null,arguments)};var _validate=Module["_validate"]=function(){return(_validate=Module["_validate"]=Module["asm"]["s"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["t"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["u"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["v"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["w"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["x"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["y"]).apply(null,arguments)};Module["cwrap"]=cwrap;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();(function(){Module.ready=new Promise(function(resolve,reject){addOnPreMain(()=>{var init=Module.cwrap("init","number",["string","number","string"]);var validate=Module.cwrap("validate","number",["number","string"]);var jsInit=function(xsd,filename){var code=init(xsd,xsd.length,filename);postMessage({file:filename,loaded:code===0})};var jsValidate=function(xml,filename){var length=lengthBytesUTF8(xml)+1;var buf=Module._malloc(length);stringToUTF8(xml,buf,length);var code=validate(buf,filename);postMessage({file:filename,valid:code===0,code:code});Module._free(buf)};resolve({init:jsInit,validate:jsValidate})});var origAbort=Module.abort;Module.abort=function(reason){reject(Error(reason));origAbort.call(this,reason)}})})(); diff --git a/packages/plugins/public/js/xmlvalidate.wasm b/packages/plugins/public/js/xmlvalidate.wasm deleted file mode 100644 index cba9071104..0000000000 Binary files a/packages/plugins/public/js/xmlvalidate.wasm and /dev/null differ diff --git a/packages/plugins/public/xml/CC-EULA.pdf b/packages/plugins/public/xml/CC-EULA.pdf deleted file mode 100644 index f479dbcaa4..0000000000 Binary files a/packages/plugins/public/xml/CC-EULA.pdf and /dev/null differ diff --git a/packages/plugins/public/xml/IEC_61850-7-2_2007B3.nsd b/packages/plugins/public/xml/IEC_61850-7-2_2007B3.nsd deleted file mode 100644 index 9635bf57ce..0000000000 --- a/packages/plugins/public/xml/IEC_61850-7-2_2007B3.nsd +++ /dev/null @@ -1,534 +0,0 @@ - - - - - COPYRIGHT (c) IEC, www.iec.ch/tc57/supportdocuments. This version of this NSD is part of IEC_61850-7-2:2010 Edition 2.1; see the IEC_61850-7-2:2010 Edition 2.1 for full legal notices. In case of any differences between the here-below code and the IEC published content, the here-below definition supersedes the IEC publication; it may contain updates. See history files. The whole document has to be taken into account to have a full description of this code component. - See www.iec.ch/CCv1 for copyright details. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/plugins/public/xml/IEC_61850-7-3_2007B3.nsd b/packages/plugins/public/xml/IEC_61850-7-3_2007B3.nsd deleted file mode 100644 index 777a13cf59..0000000000 --- a/packages/plugins/public/xml/IEC_61850-7-3_2007B3.nsd +++ /dev/null @@ -1,6228 +0,0 @@ - - - - - COPYRIGHT (c) IEC, www.iec.ch/tc57/supportdocuments. This version of this NSD is part of IEC_61850-7-3:2010 Edition 2.1; see the IEC_61850-7-3:2010 Edition 2.1 for full legal notices. In case of any differences between the here-below code and the IEC published content, the here-below definition supersedes the IEC publication; it may contain updates. See history files. The whole document has to be taken into account to have a full description of this code component. - See www.iec.ch/CCv1 for copyright details. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/plugins/public/xml/IEC_61850-7-420_2019A4.nsd b/packages/plugins/public/xml/IEC_61850-7-420_2019A4.nsd deleted file mode 100644 index b34c2af1f1..0000000000 --- a/packages/plugins/public/xml/IEC_61850-7-420_2019A4.nsd +++ /dev/null @@ -1,5520 +0,0 @@ - - - - - COPYRIGHT (c) IEC, www.iec.ch/tc57/supportdocuments. This version of this NSD is part of IEC_61850-7-420:2020 Edition 2.0; see the IEC_61850-7-420:2020 Edition 2.0 for full legal notices. In case of any differences between the here-below code and the IEC published content, the here-below definition supersedes the IEC publication; it may contain updates. See history files. The whole document has to be taken into account to have a full description of this code component. - See www.iec.ch/CCv1 for copyright details. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/plugins/public/xml/IEC_61850-7-4_2007B3.nsd b/packages/plugins/public/xml/IEC_61850-7-4_2007B3.nsd deleted file mode 100644 index aeb56b185e..0000000000 --- a/packages/plugins/public/xml/IEC_61850-7-4_2007B3.nsd +++ /dev/null @@ -1,9926 +0,0 @@ - - - - - COPYRIGHT (c) IEC, www.iec.ch/tc57/supportdocuments. This version of this NSD is part of IEC_61850-7-4:2007; see the IEC_61850-7-4:2007 for full legal notices. In case of any differences between the here-below code and the IEC published content, the here-below definition supersedes the IEC publication; it may contain updates. See history files. The whole document has to be taken into account to have a full description of this code component. - See www.iec.ch/CCv1 for copyright details. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/plugins/public/xml/IEC_61850-8-1_2003A2.nsd b/packages/plugins/public/xml/IEC_61850-8-1_2003A2.nsd deleted file mode 100644 index d43eeb2ab3..0000000000 --- a/packages/plugins/public/xml/IEC_61850-8-1_2003A2.nsd +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - COPYRIGHT (c) IEC, 2018. This version of this NSD is part of IEC 61850-8-1:2018; see the IEC 61850-8-1:2018 for full legal notices. In case of any differences between the here-below code and the IEC published content, the here-below code is the valid one; it may contain updates. See history files. The whole document has to be taken into account to have a full description of this code component. -See www.iec.ch/CCv1 for copyright details - - IEC License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/plugins/public/xml/templates.scd b/packages/plugins/public/xml/templates.scd deleted file mode 100644 index 4df107ee34..0000000000 --- a/packages/plugins/public/xml/templates.scd +++ /dev/null @@ -1,1524 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1000 - - - direct-with-enhanced-security - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1000 - - - direct-with-enhanced-security - - - - - - - - - - - 6000 - - - direct-with-enhanced-security - - - - - - - - - status-only - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - status-only - - - - - - - - - sbo-with-enhanced-security - - - 30000 - - - 600 - - - - - - - - - - - - - - - - - - - - - - - - sbo-with-enhanced-security - - - 30000 - - - 600 - - - - - - - - - - - - status-only - - - - - - - - - - - - - - - - - - - - - - - - - - - 6000 - - - direct-with-enhanced-security - - - - - - - - - status-only - - - - - - - - - IEC 61850-7-4:2007B4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - status-only - - - - - - - - - - 1000 - - - direct-with-enhanced-security - - - - - - - - - - 1000 - - - direct-with-enhanced-security - - - - - - - - - - - - - - - - - - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - IEC 61850-8-1:2003 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0.001 - - - 0 - - - - - 0.01 - - - 0 - - - - - A - - - - - A - - - - - Hz - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - on - blocked - test - test/blocked - off - - - status-only - direct-with-normal-security - sbo-with-normal-security - direct-with-enhanced-security - sbo-with-enhanced-security - - - status-only - - - not-supported - bay-control - station-control - remote-control - automatic-bay - automatic-station - automatic-remote - maintenance - process - - - y - z - a - f - p - n - µ - m - c - d - - da - h - k - M - G - T - P - E - Z - Y - - - V - A - other - Synchrophasor - - - None - ANSI Extremely Inverse - ANSI Very Inverse - ANSI Normal Inverse - ANSI Moderate Inverse - ANSI Definite Time - Long-Time Extremely Inverse - Long-Time Very Inverse - Long-Time Inverse - IEC Normal Inverse - IEC Very Inverse - IEC Inverse - IEC Extremely Inverse - IEC Short-Time Inverse - IEC Long-Time Inverse - IEC Definite Tim - Reserved - - - unknown - forward - backward - both - - - fundamental - rms - absolute - - - reserved - January - February - March - April - May - June - July - August - September - October - November - December - - - Time - WeekDay - WeekOfYear - DayOfMonth - DayOfYear - - - pulse - persistent - persistent-feedback - - - Hour - Day - Week - Month - Year - - - Va - Vb - Vc - Aa - Ab - Ac - Vab - Vbc - Vca - Vother - Aother - Synchrophasor - - - unknown - forward - backward - - - A - B - C - Synchrophasor - - - normal - high - low - high-high - low-low - - - - m - kg - s - A - K - mol - cd - deg - rad - sr - Gy - Bq - °C - Sv - F - C - S - H - V - ohm - J - N - Hz - lx - Lm - Wb - T - W - Pa - m² - m³ - m/s - m/s² - m³/s - m/m³ - M - kg/m³ - m²/s - W/m K - J/K - ppm - 1/s - rad/s - W/m² - J/m² - S/m - K/s - Pa/s - J/kg K - VA - Watts - VAr - phi - cos(phi) - Vs - V² - As - A² - A²t - VAh - Wh - VArh - V/Hz - Hz/s - char - char/s - kgm² - dB - J/Wh - W/s - l/s - dBm - h - min - Ohm/m - percent/s - - - operate-once - operate-many - - - pos-neg-zero - dir-quad-zero - - - unknown - critical - major - minor - warning - - - reserved - Monday - Tuesday - Wednesday - Thursday - Friday - Saturday - Sunday - - - Completed - Cancelled - New adjustments - Under way - - - PhaseA - PhaseB - PhaseAB - PhaseC - PhaseAC - PhaseBC - PhaseABC - None - - - Ready - InProgress - - Successful - WaitingForTrip - TripFromProtection - FaultDisappeared - WaitToComplete - CBclosed - CycleUnsuccessful - Unsuccessful - Aborted - NotReady - - - None - Open - Close-Open - Open-Close-Open - Close-Open-Close-Open - Open-Close-Open-Close-Open - more - - - MS - PER_CYCLE - CYCLE - DAY - WEEK - MONTH - YEAR - EXTERNAL - - - UNSPECIFIED - TRUE_RMS - PEAK_FUNDAMENTAL - RMS_FUNDAMENTAL - MIN - MAX - AVG - SDV - PREDICTION - RATE - P-CLASS - M-CLASS - DIFF - - - TOTAL - PERIOD - SLIDING - - - Unknown - SNTP - PTP - IRIG-B - Substation internal - - - InternalClock - LocalAreaClock - GlobalAreaClock - - - Locked - Unlocked10s - Unlocked100s - Unlocked1000s - UnlockedMoreThan1000s - - - NonDirectional - Forward - Reverse - - - Current - Breaker Status - Both current and breaker status - Other - - - PhaseAtoGround - PhaseBtoGround - PhaseCtoGround - PhaseAtoB - PhaseBtoC - PhaseCtoA - Others - - - At Start Moment - At Trip Moment - Peak Fault Value - - - Low pass - High pass - Bandpass - Bandstop - Deadband - - - Slow time delay - Fast time delay - Fast acting - Very fast acting - Not applicable / Unknown - Other - - - Ok - Warning - Alarm - - - 0.05 - 0.1 - 0.2 - 0.2S - 0.5 - 0.5S - 1 - 3 - 5 - - - 1 - 3 - 5 - 6 - 10 - - - Unknown - Normal Time - Last minute of the day has 61 seconds - Last minute of the day has 59 seconds - - - Positive or Rising - Negative or Falling - Both - Other - - - Dead Line, Dead Bus - Live Line, Dead Bus - Dead Line, Live Bus - Dead Line, Dead Bus OR Live Line, Dead Bus - Dead Line, Dead Bus OR Dead Line, Live Bus - Live Line, Dead Bus OR Dead Line, Live Bus - Dead Line, Dead Bus OR Live Line, Dead Bus OR Dead Line, Live Bus - - - Air - Water - Steam - Oil - Hydrogen - Natural gas - Butane - Propane - Waste gas - Not applicable / Unknown - Other - - - Gaseous - Liquid - Solid - Not applicable / Unknown - Other - - - IEC - EEI - - - P - I - D - PI - PD - ID - PID - - - None - Close - Open - Close and Open - - - Master/Slave - Master/Slave with fixed slave position - Master/Slave with variable slave position - Parallel operation without communication - - - Master - Slave - Independent - - - No Mode predefined - Master - Follower - Power Factor - Negative Reactance - Circulating Current - Circulating Reactive Current (var balancing) - Circulating Reactive Current by equalizing power factor - - - None - Zero Sequence Current - Zero Sequence Voltage - Negative Sequence Voltage - Phase to Phase Voltages - Phase to Ground Voltages - Positive sequence voltage - - - Overwrite existing values - Stop when full or saturated - - - Current - Voltage - Active Power - - - None - Definite Time Delayed Reset - Inverse Reset - - - None - Harmonic2 - Harmonic5 - Harmonic2and5 - WaveformAnalysis - WaveformAnalysisAndHarmonic2 - Other - WaveformAnalysisAndHarmonic5 - WaveformAnalysisAndHarmonic2AndHarmonic5 - - - Off - Without Check - With Current Check - With Breaker Status Check - With Current and Breaker Status Check - Other Checks - - - Stopped - Stopping - Started - Starting - Disabled - - - Clockwise - Counter-Clockwise - Unknown - - - Cold - Warm - Overload - - - SwitchCommand - BreakerClosed - VoltageAndCurrentLevel - - - ExternalSignal - VoltageAndCurrent - ExternalSignal or VoltageAndCurrent - - - Vector - Arithmetic - - - None - Missing valid NumEnt - Missing valid SchdIntv - Missing valid schedule values - Inconsistent values CDC - Missing valid StrTm - Other - - - Not ready - Start Time required - Ready - Running - - - Ended normally - Ended with overshoot - Cancelled: measurement was deviating - Cancelled: loss of communication with dispatch centre - Cancelled: loss of communication with local area network - Cancelled: loss of communication with the local interface - Cancelled: timeout - Cancelled: voluntarily - Cancelled: noisy environments - Cancelled: material failure - Cancelled: new set-point request - Cancelled: improper environment (blockage) - Cancelled: stability time was reached - Cancelled: immobilisation time was reached - Cancelled: equipment was in the wrong mode - Unknown causes - - - Inactive - Stage1 - Stage2 - Stage3 - - - Load Break - Disconnector - Earthing Switch - High Speed Earthing Switch - - - None - Open - Close - Open and Close - - - Automatic-synchronizing - Automatic-paralleling - Manual - Test - - - pressure only - level only - both pressure and level - - - Unknown - P - PR - PX - PXR - TPX - TPY - TPZ - TPE - - - Unused - Blocking - Permissive - Direct - Unblocking - Status - - - Internal - External - Both - - - Single Pole Tripping - Undefined - Three Pole Tripping - - - 3 phase tripping - 1 or 3 phase tripping - specific - 1 phase tripping - - - Not tuned - Tuned - Tuned but not compensated - Umax - Umax but not compensated - Umax but not compensated due to U continous limitation - - - Negative sequence - Zero sequence - Neg-pos sequence - Zero-pos sequence - Phase vector comparison - Others - - - Off - Permanent - Time window - - - Voltage - Voltage and Current - Voltage and Normally Open breaker contact - Voltage and Normally Closed breaker contact - Voltage and Normally Open and Normally Closed breaker contacts - Normally Open breaker contact - Normally Closed breaker contact - Both Normally Open and Normally Closed breaker contacts - - - Off - Operate - Echo - Echo and Operate - - - - diff --git a/packages/plugins/snowpack.config.mjs b/packages/plugins/snowpack.config.mjs deleted file mode 100644 index 2f0bd15477..0000000000 --- a/packages/plugins/snowpack.config.mjs +++ /dev/null @@ -1,34 +0,0 @@ -export default { - plugins: ['@snowpack/plugin-typescript'], - packageOptions: { - external: [ - '@web/dev-server-core', - '@web/dev-server-esbuild', - 'esbuild', - 'crypto', - ], - }, - exclude: [ - '**/*.@(spec|test).@(js|mjs)', - '**/test/**/*', - '**/out-tsc/**/*', - '**/.editorconfig', - '**/.eslintrc.cjs', - '**/.git/**/*', - '**/.gitignore', - '**/.idea/**/*', - '**/.travis.yml', - '**/package*', - '**/tsconfig.json', - '**/web-test-runner.config.mjs', - '**/node_modules/**/*', - ], - workspaceRoot: '../../', - mount: { - '../open-scd/': '/open-scd/', - './': '/', - }, - alias: { - '@openscd/open-scd': '../open-scd/', - }, -}; diff --git a/packages/plugins/src/editors/Cleanup.ts b/packages/plugins/src/editors/Cleanup.ts deleted file mode 100644 index 6296511847..0000000000 --- a/packages/plugins/src/editors/Cleanup.ts +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; - -import { css, html, LitElement, property, TemplateResult } from 'lit-element'; - -import { styles } from './templates/foundation.js'; - -import './cleanup/datasets-container.js'; -import './cleanup/control-blocks-container.js'; -import './cleanup/datatypes-container.js'; - -/** An editor [[`plugin`]] for cleaning SCL references and definitions. */ -export default class Cleanup extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - render(): TemplateResult { - return html` -
- - - -
- `; - } - - static styles = css` - ${styles} - - :host { - width: 100vw; - } - - @media (max-width: 799px) { - .cleanup { - flex-direction: column; - } - } - - @media (min-width: 800px) { - .cleanup { - max-height: 60vh; - } - } - - cleanup-datasets, cleanup-control-blocks, cleanup-data-types { - display: flex; - flex: 1; - flex-direction: column; - justify-content: space-between; - } - - .cleanup { - display: flex; - flex-wrap: wrap; - gap: 20px; - padding: 20px; - } - } - `; -} diff --git a/packages/plugins/src/editors/Communication.ts b/packages/plugins/src/editors/Communication.ts deleted file mode 100644 index 605a6af9a3..0000000000 --- a/packages/plugins/src/editors/Communication.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { LitElement, html, TemplateResult, property, css } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-fab'; - -import './communication/subnetwork-editor.js'; -import { newWizardEvent, isPublic } from '@openscd/open-scd/src/foundation.js'; - -import { createElement } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { createSubNetworkWizard } from '../wizards/subnetwork.js'; - -/** An editor [[`plugin`]] for editing the `Communication` section. */ -export default class CommunicationPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - /** - * Creates the Communication Element and returns the created Element - * @returns {Element} Communication `Element` - */ - private createCommunication(): Element { - const element: Element = createElement(this.doc, 'Communication', {}); - this.dispatchEvent( - newActionEvent({ - new: { - parent: this.doc.documentElement, - element: element, - }, - }) - ); - return element; - } - - /** Opens a [[`WizardDialog`]] for creating a new `SubNetwork` element. */ - private openCreateSubNetworkWizard(): void { - const parent = - this.doc.querySelector(':root > Communication') || - this.createCommunication(); - - this.dispatchEvent(newWizardEvent(createSubNetworkWizard(parent!))); - } - - render(): TemplateResult { - if (!this.doc?.querySelector(':root > Communication >SubNetwork')) - return html`

- ${get('communication.missing')} this.openCreateSubNetworkWizard()} - > -

`; - - return html` this.openCreateSubNetworkWizard()} - > -
- ${Array.from(this.doc.querySelectorAll('SubNetwork') ?? []) - .filter(isPublic) - .map( - subnetwork => - html`` - )} -
`; - } - - static styles = css` - :host { - width: 100vw; - } - - h1 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - transition: background-color 150ms linear; - } - - section { - outline: none; - padding: 8px 12px 16px; - } - - subnetwork-editor { - margin: 8px 12px 16px; - } - - mwc-fab { - position: fixed; - bottom: 32px; - right: 32px; - } - `; -} diff --git a/packages/plugins/src/editors/GooseSubscriberDataBinding.ts b/packages/plugins/src/editors/GooseSubscriberDataBinding.ts deleted file mode 100644 index 4d1c3a75a3..0000000000 --- a/packages/plugins/src/editors/GooseSubscriberDataBinding.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { css, html, LitElement, property, TemplateResult } from 'lit-element'; - -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; - -import './subscription/fcda-binding-list.js'; -import './subscription/later-binding/ext-ref-ln-binding-list.js'; - -/** An editor [[`plugin`]] for Subscribe Data Binding (GOOSE). */ -export default class GooseSubscribeDataBindingPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property() - nsdoc!: Nsdoc; - - render(): TemplateResult { - return html`
-
- - - - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: calc(100vh - 136px); - } - - .column { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: auto; - } - `; -} diff --git a/packages/plugins/src/editors/GooseSubscriberLaterBinding.ts b/packages/plugins/src/editors/GooseSubscriberLaterBinding.ts deleted file mode 100644 index c77bc1f754..0000000000 --- a/packages/plugins/src/editors/GooseSubscriberLaterBinding.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { css, html, LitElement, property, TemplateResult } from 'lit-element'; - -import './subscription/fcda-binding-list.js'; -import './subscription/later-binding/ext-ref-later-binding-list.js'; - -/** An editor [[`plugin`]] for Subscribe Later Binding (GOOSE). */ -export default class GooseSubscribeLaterBindingPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - render(): TemplateResult { - return html`
-
- - - - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: calc(100vh - 136px); - } - - .column { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: auto; - } - `; -} diff --git a/packages/plugins/src/editors/GooseSubscriberMessageBinding.ts b/packages/plugins/src/editors/GooseSubscriberMessageBinding.ts deleted file mode 100644 index 282c943434..0000000000 --- a/packages/plugins/src/editors/GooseSubscriberMessageBinding.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { - css, - html, - LitElement, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-radio'; -import '@material/mwc-formfield'; -import { RadioListItem } from '@material/mwc-list/mwc-radio-list-item'; - -import './subscription/goose/subscriber-list.js'; -import './subscription/goose/goose-list.js'; -import './subscription/ied-list.js'; -import { newViewEvent, View, ViewEvent } from './subscription/foundation.js'; - -/** Defining view outside the class, which makes it persistent. */ -let view: View = View.PUBLISHER; - -/** An editor [[`plugin`]] for subscribing IEDs to GOOSE messages. */ -export default class GooseSubscriberMessageBindingPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @query('#goosePublisherView') - goosePublisherView!: RadioListItem; - - @query('#gooseSubscriberView') - gooseSubscriberView!: RadioListItem; - - @query('div[class="container"]') - listDiv!: Element; - - constructor() { - super(); - this.addEventListener('view', (evt: ViewEvent) => { - view = evt.detail.view; - this.requestUpdate(); - }); - } - - firstUpdated(): void { - view == View.PUBLISHER - ? this.goosePublisherView.setAttribute('checked', '') - : this.gooseSubscriberView.setAttribute('checked', ''); - } - - render(): TemplateResult { - return html`
- - - this.listDiv.dispatchEvent(newViewEvent(View.PUBLISHER))} - > - - - - this.listDiv.dispatchEvent(newViewEvent(View.SUBSCRIBER))} - > - -
- ${view == View.PUBLISHER - ? html`` - : html``} - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: 86vh; - } - - .row { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: scroll; - } - `; -} diff --git a/packages/plugins/src/editors/IED.ts b/packages/plugins/src/editors/IED.ts deleted file mode 100644 index 052a1309c0..0000000000 --- a/packages/plugins/src/editors/IED.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { - css, - html, - LitElement, - property, - PropertyValues, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; -import { nothing } from 'lit-html'; - -import '@material/mwc-list/mwc-check-list-item'; -import '@material/mwc-list/mwc-radio-list-item'; - -import '@openscd/open-scd/src/oscd-filter-button.js'; -import { SelectedItemsChangedEvent } from '@openscd/open-scd/src/oscd-filter-button.js'; - -import './ied/ied-container.js'; -import './ied/element-path.js'; - -import { - compareNames, - getDescriptionAttribute, - getNameAttribute, -} from '@openscd/open-scd/src/foundation.js'; -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; -import { getIcon } from '@openscd/open-scd/src/icons/icons.js'; - -/** An editor [[`plugin`]] for editing the `IED` section. */ -export default class IedPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - - @property({ type: Number }) - editCount = -1; - - /** All the nsdoc files that are being uploaded via the settings. */ - @property() - nsdoc!: Nsdoc; - - @state() - selectedIEDs: string[] = []; - - @state() - selectedLNClasses: string[] = []; - - @state() - private get iedList(): Element[] { - return this.doc - ? Array.from(this.doc.querySelectorAll(':root > IED')).sort((a, b) => - compareNames(a, b) - ) - : []; - } - - @state() - private get lnClassList(): string[][] { - const currentIed = this.selectedIed; - const uniqueLNClassList: string[] = []; - if (currentIed) { - return Array.from(currentIed.querySelectorAll('LN0, LN')) - .filter(element => element.hasAttribute('lnClass')) - .filter(element => { - const lnClass = element.getAttribute('lnClass') ?? ''; - if (uniqueLNClassList.includes(lnClass)) { - return false; - } - uniqueLNClassList.push(lnClass); - return true; - }) - .sort((a, b) => { - const aLnClass = a.getAttribute('lnClass') ?? ''; - const bLnClass = b.getAttribute('lnClass') ?? ''; - - return aLnClass.localeCompare(bLnClass); - }) - .map(element => { - const lnClass = element.getAttribute('lnClass'); - const label = this.nsdoc.getDataDescription(element).label; - return [lnClass, label]; - }) as string[][]; - } - return []; - } - - @state() - private get selectedIed(): Element | undefined { - // When there is no IED selected, or the selected IED has no parent (IED has been removed) - // select the first IED from the List. - if (this.selectedIEDs.length >= 1) { - const iedList = this.iedList; - return iedList.find(element => { - const iedName = getNameAttribute(element); - return this.selectedIEDs[0] === iedName; - }); - } - return undefined; - } - - lNClassListOpenedOnce = false; - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When the document is updated, we reset the selected IED if it no longer exists - const isDocumentUpdated = - _changedProperties.has('doc') || - _changedProperties.has('editCount') || - _changedProperties.has('nsdoc'); - - if (isDocumentUpdated) { - // if the IED exists, retain selection - const iedExists = this.doc?.querySelector( - `IED[name="${this.selectedIEDs[0]}"]` - ); - - if (iedExists) return; - - this.selectedIEDs = []; - this.selectedLNClasses = []; - this.lNClassListOpenedOnce = false; - - const iedList = this.iedList; - if (iedList.length > 0) { - const iedName = getNameAttribute(iedList[0]); - if (iedName) { - this.selectedIEDs = [iedName]; - } - } - } - } - - private calcSelectedLNClasses(): string[] { - const somethingSelected = this.selectedLNClasses.length > 0; - const lnClasses = this.lnClassList.map(lnClassInfo => lnClassInfo[0]); - - let selectedLNClasses = lnClasses; - - if (somethingSelected) { - selectedLNClasses = lnClasses.filter(lnClass => - this.selectedLNClasses.includes(lnClass) - ); - } - - return selectedLNClasses; - } - - render(): TemplateResult { - const iedList = this.iedList; - if (iedList.length > 0) { - return html`
-
-

${get('filters')}:

- - - ${iedList.map(ied => { - const name = getNameAttribute(ied); - const descr = getDescriptionAttribute(ied); - const type = ied.getAttribute('type'); - const manufacturer = ied.getAttribute('manufacturer'); - return html` - ${name} ${descr ? html` (${descr})` : html``} - - ${type} ${type && manufacturer ? html`—` : nothing} - ${manufacturer} - - `; - })} - - - - ${getIcon('lNIcon')} - ${this.lnClassList.map(lnClassInfo => { - const value = lnClassInfo[0]; - const label = lnClassInfo[1]; - return html` - ${label} - `; - })} - - - -
- - -
`; - } - return html`

- ${get('iededitor.missing')} -

`; - } - - static styles = css` - :host { - width: 100vw; - } - - section { - padding: 8px 12px 16px; - } - - .header { - display: flex; - } - - h1 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - } - - .elementPath { - margin-left: auto; - padding-right: 12px; - } - `; -} diff --git a/packages/plugins/src/editors/Protocol104.ts b/packages/plugins/src/editors/Protocol104.ts deleted file mode 100644 index 0d9218ef67..0000000000 --- a/packages/plugins/src/editors/Protocol104.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { - css, - html, - LitElement, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-fab'; -import '@material/mwc-radio'; -import '@material/mwc-formfield'; - -import { RadioListItem } from '@material/mwc-list/mwc-radio-list-item'; - -import './protocol104/network-container.js'; -import './protocol104/values-container.js'; - -import { - newViewEvent, - View, - VIEW_EVENT_NAME, - ViewEvent, -} from './protocol104/foundation/foundation.js'; - -/** Defining view outside the class, which makes it persistent. */ -let selectedViewProtocol104Plugin: View = View.VALUES; - -export default class Communication104Plugin extends LitElement { - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @query('#byValuesRadio') - byValuesRadio!: RadioListItem; - - @query('#byNetworkRadio') - byNetworkRadio!: RadioListItem; - - @query('div#containers') - listDiv!: Element; - - constructor() { - super(); - - this.addEventListener(VIEW_EVENT_NAME, (evt: ViewEvent) => { - selectedViewProtocol104Plugin = evt.detail.view; - this.requestUpdate(); - }); - } - - firstUpdated(): void { - selectedViewProtocol104Plugin == View.VALUES - ? this.byValuesRadio.setAttribute('checked', '') - : this.byNetworkRadio.setAttribute('checked', ''); - } - - render(): TemplateResult { - return html`
-
- - - this.listDiv.dispatchEvent(newViewEvent(View.VALUES))} - > - - - - this.listDiv.dispatchEvent(newViewEvent(View.NETWORK))} - > - -
- ${selectedViewProtocol104Plugin == View.VALUES - ? html`` - : html``} -
-
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - section { - padding: 8px 12px 16px; - } - `; -} diff --git a/packages/plugins/src/editors/Publisher.ts b/packages/plugins/src/editors/Publisher.ts deleted file mode 100644 index 656dbc25af..0000000000 --- a/packages/plugins/src/editors/Publisher.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { - css, - html, - LitElement, - property, - state, - TemplateResult, -} from 'lit-element'; -import { classMap } from 'lit-html/directives/class-map'; - -import '@material/mwc-formfield'; -import '@material/mwc-radio'; - -import './publisher/report-control-editor.js'; -import './publisher/gse-control-editor.js'; -import './publisher/sampled-value-control-editor.js'; -import './publisher/data-set-editor.js'; - -/** An editor [[`plugin`]] to configure `Report`, `GOOSE`, `SampledValue` control blocks and its `DataSet` */ -export default class PublisherPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @state() - private publisherType: 'Report' | 'GOOSE' | 'SampledValue' | 'DataSet' = - 'GOOSE'; - - render(): TemplateResult { - return html`
- (this.publisherType = 'Report')} - > (this.publisherType = 'GOOSE')} - > (this.publisherType = 'SampledValue')} - > (this.publisherType = 'DataSet')} - > -
- `; - } - - static styles = css` - .hidden { - display: none; - } - - .publishertypeselector { - margin: 4px 8px 8px; - background-color: var(--mdc-theme-surface); - width: calc(100% - 16px); - justify-content: space-around; - } - `; -} diff --git a/packages/plugins/src/editors/SMVSubscriberDataBinding.ts b/packages/plugins/src/editors/SMVSubscriberDataBinding.ts deleted file mode 100644 index a38b09d16c..0000000000 --- a/packages/plugins/src/editors/SMVSubscriberDataBinding.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { css, html, LitElement, property, TemplateResult } from 'lit-element'; - -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; - -import './subscription/fcda-binding-list.js'; -import './subscription/later-binding/ext-ref-ln-binding-list.js'; - -/** An editor [[`plugin`]] for Subscribe Data Binding (SMV). */ -export default class SMVSubscribeDataBindingPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property() - nsdoc!: Nsdoc; - - render(): TemplateResult { - return html`
-
- - - - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: calc(100vh - 136px); - } - - .column { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: auto; - } - `; -} diff --git a/packages/plugins/src/editors/SMVSubscriberLaterBinding.ts b/packages/plugins/src/editors/SMVSubscriberLaterBinding.ts deleted file mode 100644 index f8d5be3c00..0000000000 --- a/packages/plugins/src/editors/SMVSubscriberLaterBinding.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { css, html, LitElement, property, TemplateResult } from 'lit-element'; - -import './subscription/fcda-binding-list.js'; -import './subscription/later-binding/ext-ref-later-binding-list.js'; - -/** An editor [[`plugin`]] for Subscribe Later Binding (SMV). */ -export default class SMVSubscribeLaterBindingPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - render(): TemplateResult { - return html`
-
- - - - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: calc(100vh - 136px); - } - - .column { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: auto; - } - `; -} diff --git a/packages/plugins/src/editors/SMVSubscriberMessageBinding.ts b/packages/plugins/src/editors/SMVSubscriberMessageBinding.ts deleted file mode 100644 index 93e857db9b..0000000000 --- a/packages/plugins/src/editors/SMVSubscriberMessageBinding.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { - css, - html, - LitElement, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import { RadioListItem } from '@material/mwc-list/mwc-radio-list-item.js'; - -import './subscription/sampledvalues/subscriber-list.js'; -import './subscription/sampledvalues/smv-list.js'; -import './subscription/ied-list.js'; -import { newViewEvent, View, ViewEvent } from './subscription/foundation.js'; - -/** Defining view outside the class, which makes it persistent. */ -let view: View = View.PUBLISHER; - -/** An editor [[`plugin`]] for subscribing IEDs to Sampled Values. */ -export default class SMVSubscriberMessageBindingPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @query('#smvPublisherView') - smvPublisherView!: RadioListItem; - - @query('#smvSubscriberView') - smvSubscriberView!: RadioListItem; - - @query('div[class="container"]') - listDiv!: Element; - - constructor() { - super(); - this.addEventListener('view', (evt: ViewEvent) => { - view = evt.detail.view; - this.requestUpdate(); - }); - } - - firstUpdated(): void { - view == View.PUBLISHER - ? this.smvPublisherView.setAttribute('checked', '') - : this.smvSubscriberView.setAttribute('checked', ''); - } - - render(): TemplateResult { - return html`
- - - this.listDiv.dispatchEvent(newViewEvent(View.PUBLISHER))} - > - - - - this.listDiv.dispatchEvent(newViewEvent(View.SUBSCRIBER))} - > - -
- ${view == View.PUBLISHER - ? html`` - : html``} - -
-
`; - } - - static styles = css` - :host { - width: 100vw; - } - - .container { - display: flex; - padding: 8px 6px 16px; - height: 86vh; - } - - .row { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: scroll; - } - `; -} diff --git a/packages/plugins/src/editors/SingleLineDiagram.ts b/packages/plugins/src/editors/SingleLineDiagram.ts deleted file mode 100644 index 3792f11247..0000000000 --- a/packages/plugins/src/editors/SingleLineDiagram.ts +++ /dev/null @@ -1,662 +0,0 @@ -import { - css, - html, - LitElement, - property, - PropertyValues, - query, - state, - TemplateResult, -} from 'lit-element'; -import panzoom from 'panzoom'; - -import { - compareNames, - getDescriptionAttribute, - getNameAttribute, - getPathNameAttribute, - identity, - newWizardEvent, - SCLTag, -} from '@openscd/open-scd/src/foundation.js'; -import { - addLabelToBay, - addLabelToBusBar, - createBayElement, - createBusBarElement, - createConductingEquipmentElement, - createConnectivityNodeElement, - createPowerTransformerElement, - createSubstationElement, - createTerminalElement, - createVoltageLevelElement, - drawBusBarRoute, - drawCNodeConnections, - getAbsolutePosition, - getAbsolutePositionBusBar, - getAbsolutePositionTerminal, - getBusBarLength, - getConnectivityNodesDrawingPosition, - getDirections, -} from './singlelinediagram/sld-drawing.js'; -import { - getCommonParentElement, - getConnectedTerminals, - isBusBar, -} from './singlelinediagram/foundation.js'; -import { isSCLNamespace } from '@openscd/open-scd/src/schemas.js'; -import { wizards } from './singlelinediagram/wizards/wizard-library.js'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; -import '@material/mwc-textfield'; - -/* - * We need a variable outside the plugin to save the selected substation, because the Plugin is created - * more than once during working with the SLD, for instance when opening a Wizard to edit equipment. - */ -let sldEditorSelectedSubstation: Element | undefined; -/* - * We will also add an Event Listener when a new document is opened. We then want to reset the selection - * so setting it to undefined will set the selected Substation again on the first in the list. - */ -function onOpenDocResetSelectedSubstation() { - sldEditorSelectedSubstation = undefined; -} -addEventListener('open-doc', onOpenDocResetSelectedSubstation); - -/** - * Main class plugin for Single Line Diagram editor. - */ -export default class SingleLineDiagramPlugin extends LitElement { - // The full given XML document. - @property({ attribute: false }) - doc!: XMLDocument; - - // Container for giving the panzoom to. - @query('#panzoom') panzoomContainer!: HTMLElement; - // The main canvas to draw everything on. - @query('#svg') svg!: SVGGraphicsElement; - - private get substations(): Element[] { - return this.doc - ? Array.from(this.doc.querySelectorAll(':root > Substation')).sort( - (a, b) => compareNames(a, b) - ) - : []; - } - - @state() - private set selectedSubstation(element: Element | undefined) { - sldEditorSelectedSubstation = element; - } - - private get selectedSubstation(): Element | undefined { - if (sldEditorSelectedSubstation === undefined) { - const substationList = this.substations; - if (substationList.length > 0) { - sldEditorSelectedSubstation = substationList[0]; - } - } - return sldEditorSelectedSubstation; - } - - /** - * Get all the Power Transformers from an element. - */ - private getPowerTransformers(parentElement: Element): Element[] { - return Array.from( - parentElement.querySelectorAll('PowerTransformer') - ).filter(isSCLNamespace); - } - - /** - * Get all the Voltage Levels from the substation. - */ - private getVoltageLevels(substationElement: Element): Element[] { - return Array.from( - substationElement.querySelectorAll('VoltageLevel') - ).filter(isSCLNamespace); - } - - /** - * Get all the BusBars from the voltage level. - */ - private getBusBars(voltageLevelElement: Element): Element[] { - return Array.from(voltageLevelElement.querySelectorAll('Bay')) - .filter(isSCLNamespace) - .filter(bay => isBusBar(bay)); - } - - /** - * Get all the bays from the voltage level. - */ - private getBays(voltageLevelElement: Element): Element[] { - return Array.from(voltageLevelElement.querySelectorAll('Bay')) - .filter(isSCLNamespace) - .filter(bay => !isBusBar(bay)); - } - - /** - * Get all the Conducting Equipment from a Bay. - * @param bayElement - The Bay to search in. - */ - private getConductingEquipments(bayElement: Element): Element[] { - return Array.from( - bayElement.querySelectorAll('ConductingEquipment') - ).filter(isSCLNamespace); - } - - /** - * Get all the Connectivity Nodes from a Bay/Busbar. - * @param bayElement - The Bay/Busbar to search in. - */ - private getConnectivityNode(bayElement: Element): Element[] { - return Array.from(bayElement.querySelectorAll('ConnectivityNode')) - .filter(isSCLNamespace) - .filter(cNode => cNode.getAttribute('name') !== 'grounded'); - } - - /** - * Search for Equipment (ConductionEquipment or PowerTransformer) which has a terminal wth a connectivityNode - * tha is the same as the passed pathName. - * @param parentElement - The Element to search in for Equipment. - * @param pathName - The PathName to search for in the Terminal. - */ - private findEquipment( - parentElement: Element, - pathName: string | undefined - ): Element[] { - return Array.from( - parentElement.querySelectorAll('ConductingEquipment, PowerTransformer') - ) - .filter(isSCLNamespace) - .filter(element => - element.querySelector(`Terminal[connectivityNode="${pathName}"]`) - ); - } - - /** - * Draw all equipment and connections of the selected Substation. - */ - private drawSubstation(substation: Element): void { - const substationGroup = createSubstationElement(substation); - this.svg.appendChild(substationGroup); - - this.drawPowerTransformers(substation, substationGroup); - this.drawVoltageLevels(substation, substationGroup); - } - - /** - * Draw all available `PowerTransformer`s of passed parent element. - * Should only be a element. - * @param parentElement - The parent element to search for PowerTransformers. - * @param parentGroup - The SVG Group to which to add the PowerTransformer. - */ - private drawPowerTransformers( - parentElement: Element, - parentGroup: SVGElement - ): void { - this.getPowerTransformers(parentElement).forEach(powerTransformerElement => - this.drawPowerTransformer(parentGroup, powerTransformerElement) - ); - } - - /** - * Draw an SVG from the passed PowerTransformer Element. - * Should only be a element. - * @param parentGroup - The SVG Group to which to add the PowerTransformer. - * @param powerTransformerElement - The PowerTransformer to draw. - */ - private drawPowerTransformer( - parentGroup: SVGElement, - powerTransformerElement: Element - ): void { - const powerTransformerGroup = createPowerTransformerElement( - powerTransformerElement, - (event: Event) => this.openEditWizard(event, powerTransformerElement) - ); - parentGroup.appendChild(powerTransformerGroup); - } - - /** - * Draw all available Voltage Levels of the passed Substation Element. - * Should only be a element. - * @param substationElement - The substation containing the voltage levels. - * @param substationGroup - The group to which to add the SVGs. - */ - private drawVoltageLevels( - substationElement: Element, - substationGroup: SVGElement - ): void { - // First draw all the devices on the SVG for all voltage levels. - this.getVoltageLevels(substationElement).forEach(voltageLevelElement => { - const voltageLevelGroup = createVoltageLevelElement(voltageLevelElement); - substationGroup.appendChild(voltageLevelGroup); - - this.drawPowerTransformers(voltageLevelElement, voltageLevelGroup); - this.drawBays(voltageLevelElement, voltageLevelGroup); - this.drawBusBars(voltageLevelElement, voltageLevelGroup); - }); - - // After all devices are drawn we can draw the connections between the devices. - // And also add the label on the correct place, we now know where the boundaries are. - this.getVoltageLevels(substationElement).forEach(voltageLevelElement => { - this.getBusBars(voltageLevelElement).forEach(busbarElement => { - this.drawBusBarConnections(substationElement, this.svg, busbarElement); - - addLabelToBusBar(this.svg, busbarElement, (event: Event) => - this.openEditWizard(event, busbarElement) - ); - }); - - this.getBays(voltageLevelElement).forEach(bayElement => { - this.drawBayConnections(substationElement, this.svg, bayElement); - - addLabelToBay(this.svg, bayElement, (event: Event) => - this.openEditWizard(event, bayElement) - ); - }); - }); - } - - /** - * Draw all available Bays of the passed Voltage Level Element. - * Should only be a element. - * @param voltageLevelElement - The Voltage Level containing the bays. - * @param voltageLevelGroup - The group to which to add the SVGs. - * */ - private drawBays( - voltageLevelElement: Element, - voltageLevelGroup: SVGElement - ): void { - this.getBays(voltageLevelElement).forEach(bayElement => { - const bayGroup = createBayElement(bayElement); - voltageLevelGroup.appendChild(bayGroup); - - this.drawPowerTransformers(bayElement, bayGroup); - this.drawConductingEquipments(bayElement, bayGroup); - this.drawConnectivityNodes(bayElement, bayGroup); - }); - } - - /** - * Draw all available Conducting Equipments of the passed Bay Element. - * Should only be a element. - * @param bayElement - The Bay containing the Conducting Equipment. - * @param bayGroup - The group to which to add the SVGs. - */ - private drawConductingEquipments( - bayElement: Element, - bayGroup: SVGElement - ): void { - this.getConductingEquipments(bayElement) - .filter( - conductingEquipmentElement => - Array.from( - conductingEquipmentElement.querySelectorAll('Terminal') - ).filter( - terminal => terminal.getAttribute('cNodeName') !== 'grounded' - ).length !== 0 - ) - .forEach(conductingEquipmentElement => { - const conductingEquipmentGroup = createConductingEquipmentElement( - conductingEquipmentElement, - (event: Event) => - this.openEditWizard(event, conductingEquipmentElement!) - ); - bayGroup.appendChild(conductingEquipmentGroup); - }); - } - - /** - * Draw all available Connectivity Nodes of the passed Bay Element. - * @param bayElement - The Bay containing the Connectivity Nodes. - * @param bayGroup - The group to which to add the SVGs. - * */ - private drawConnectivityNodes( - bayElement: Element, - bayGroup: SVGElement - ): void { - this.getConnectivityNode(bayElement) - .filter(cNode => getConnectedTerminals(cNode).length > 0) - .forEach(cNode => { - const cNodegroup = createConnectivityNodeElement( - cNode, - (event: Event) => this.openEditWizard(event, cNode) - ); - - bayGroup.appendChild(cNodegroup); - }); - } - - /** - * Draw all connections between the different Equipment in the Bay and the Bay has with other Equipment outside - * the bay. - * @param rootElement - The Element containing all the other elements to which the Bay is connected. - * @param rootGroup - The SVG Element that contains all groups from the elements to add path to. - * @param bayElement - The Bay that holds the Connectivity Node to connect with. - */ - private drawBayConnections( - rootElement: Element, - rootGroup: SVGElement, - bayElement: Element - ): void { - this.getConnectivityNode(bayElement).forEach(cNode => { - this.findEquipment(rootElement, getPathNameAttribute(cNode)).forEach( - equipmentElement => { - const commonParentElement = getCommonParentElement( - cNode, - equipmentElement, - bayElement - ); - const sides = getDirections(equipmentElement, cNode); - - const elementsTerminalPosition = getAbsolutePositionTerminal( - equipmentElement, - sides.startDirection - ); - - const cNodePosition = getConnectivityNodesDrawingPosition( - cNode, - sides.endDirection - ); - - rootGroup - .querySelectorAll(`g[id="${identity(commonParentElement)}"]`) - .forEach(eq => - drawCNodeConnections( - cNodePosition, - elementsTerminalPosition, - eq - ) - ); - - const terminalElement = equipmentElement.querySelector( - `Terminal[connectivityNode="${cNode.getAttribute('pathName')}"]` - ); - - const terminal = createTerminalElement( - terminalElement!, - sides.startDirection, - (event: Event) => this.openEditWizard(event, terminalElement!) - ); - - rootGroup - .querySelectorAll(`g[id="${identity(equipmentElement)}"]`) - .forEach(eq => eq.appendChild(terminal)); - } - ); - }); - } - - /** - * Draw all available Busbars of the passed Voltage Level Element. - * @param voltageLevelElement - The Voltage Level containing the Busbars. - * @param voltageLevelGroup - The group to which to add the SVGs. - */ - private drawBusBars( - voltageLevelElement: Element, - voltageLevelGroup: SVGElement - ): void { - this.getBusBars(voltageLevelElement).forEach(busbarElement => { - const busbarGroup = createBusBarElement( - busbarElement, - getBusBarLength(voltageLevelElement) - ); - voltageLevelGroup.appendChild(busbarGroup); - }); - } - - /** - * Draw all the connections a Busbar has with other Equipment. - * @param rootElement - The Element containing all the other elements to which the Busbar is connected. - * @param rootGroup - The SVG Element that contains all groups from the elements to add path to. - * @param busbarElement - The Busbar that holds the Connectivity Node to connect with. - */ - private drawBusBarConnections( - rootElement: Element, - rootGroup: SVGElement, - busbarElement: Element - ): void { - const pathName = getPathNameAttribute(busbarElement.children[0]); - const busbarPosition = getAbsolutePositionBusBar(busbarElement); - - this.findEquipment(rootElement, pathName).forEach(element => { - const parentElement = element.parentElement; - const elementPosition = getAbsolutePosition(element); - - const elementsTerminalSide = - busbarPosition.y < elementPosition.y ? 'top' : 'bottom'; - - const elementsTerminalPosition = getAbsolutePositionTerminal( - element, - elementsTerminalSide - ); - - const busbarTerminalPosition = { - x: elementsTerminalPosition.x, - y: busbarPosition.y, - }; - - const terminalElement = element.querySelector( - `Terminal[connectivityNode="${pathName}"]` - ); - - rootGroup - .querySelectorAll(`g[id="${identity(parentElement)}"]`) - .forEach(eq => - drawBusBarRoute( - busbarTerminalPosition, - elementsTerminalPosition, - eq - ) - ); - - const terminal = createTerminalElement( - terminalElement!, - elementsTerminalSide, - (event: Event) => this.openEditWizard(event, terminalElement!) - ); - - rootGroup - .querySelectorAll(`g[id="${identity(element)}"]`) - .forEach(eq => eq.appendChild(terminal)); - }); - } - - /** - * Remove all the child elements (and descendants) from the SVG Element, to have a clean start. - */ - private clearSVG(): void { - while (this.svg.firstChild) { - this.svg.removeChild(this.svg.lastChild!); - } - } - - /** - * Draw all the elements of the selected Substation. - */ - drawSVGElements(): void { - // First clean the existing drawing, because the selected substation may have changed. - this.clearSVG(); - - // Only draw the diagram if there is a substation selected. - const selectedSubstationElement = this.selectedSubstation; - if (selectedSubstationElement) { - this.drawSubstation(selectedSubstationElement); - - // Set the new size of the SVG. - const bbox = this.svg.getBBox(); - this.svg.setAttribute( - 'viewBox', - bbox.x - - 10 + - ' ' + - (bbox.y - 10) + - ' ' + - (bbox.width + 20) + - ' ' + - (bbox.height + 20) - ); - this.svg.setAttribute('width', bbox.width + 20 + 'px'); - this.svg.setAttribute('height', bbox.height + 20 + 'px'); - - panzoom(this.panzoomContainer, { - zoomSpeed: 0.2, - maxZoom: 1.5, - minZoom: 0.2, - initialZoom: 0.5, - }); - } - } - - /** - * Open an Edit wizard for an element. - * @param element - The element to show the wizard for. - */ - openEditWizard(event: Event, element: Element): void { - const wizard = wizards[element.tagName].edit(element); - if (wizard) { - this.dispatchEvent(newWizardEvent(wizard)); - event.stopPropagation(); - } - } - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When the document is updated, we also will retrieve the history again, because probably it has changed. - if ( - _changedProperties.has('doc') || - _changedProperties.has('selectedSubstation') - ) { - this.drawSVGElements(); - } - } - - onSelect(event: SingleSelectedEvent): void { - // Set the selected Substation. - this.selectedSubstation = this.substations[event.detail.index]; - this.requestUpdate('selectedSubstation'); - } - - private renderSubstationSelector(): TemplateResult { - const substationList = this.substations; - if (substationList.length > 0) { - if (substationList.length > 1) { - return html` - - ${substationList.map(substation => { - const name = getNameAttribute(substation); - const description = getDescriptionAttribute(substation); - return html` - ${name}${description !== undefined - ? ' (' + description + ')' - : ''} - `; - })} - - `; - } - - const selectedSubstationElement = this.selectedSubstation!; - const name = getNameAttribute(selectedSubstationElement); - const description = getDescriptionAttribute(selectedSubstationElement); - return html` - - - `; - } - return html` -

- ${get('substation.missing')} -

- `; - } - - render(): TemplateResult { - // TODO: Width and Height should be a percentage, not fixed height/width. - return html` ${this.renderSubstationSelector()} - -
-
- -
-
`; - } - - static styles = css` - h1 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - } - - #substationSelector, - #selectedSubstation { - width: 35vw; - margin: 0.67em 0 0 0.67em; - } - - #noSubstationSelector { - color: var(--base1); - } - - .sldContainer { - overflow: hidden; - } - - g { - pointer-events: bounding-box; - } - - g[type='Bay'] > g[type='BayLabel'] { - visibility: hidden; - } - g[type='Bay']:hover > g[type='BayLabel'] { - visibility: visible; - } - - g[type='Busbar'] > g[type='BusbarLabel'] { - visibility: hidden; - } - g[type='Busbar'] > g[type='BusbarLabel'] > text, - g[type='Busbar']:hover > g[type='BusbarLabel'] { - visibility: visible; - } - - g[type='Bay']:hover, - g[type='Busbar']:hover, - g[type='ConductingEquipment']:hover, - g[type='ConnectivityNode']:hover, - g[type='PowerTransformer']:hover, - g[type='Terminal']:hover { - outline: 2px dashed var(--mdc-theme-primary); - transition: transform 200ms linear, box-shadow 250ms linear; - } - `; -} diff --git a/packages/plugins/src/editors/Substation.ts b/packages/plugins/src/editors/Substation.ts deleted file mode 100644 index f52b95db6e..0000000000 --- a/packages/plugins/src/editors/Substation.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { LitElement, html, TemplateResult, property, css } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-fab'; - -import './substation/zeroline-pane.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { wizards } from '../wizards/wizard-library.js'; - -/** An editor [[`plugin`]] for editing the `Substation` section. */ -export default class SubstationPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - /** Opens a [[`WizardDialog`]] for creating a new `Substation` element. */ - openCreateSubstationWizard(): void { - const wizard = wizards['Substation'].create(this.doc.documentElement); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - render(): TemplateResult { - return html` - ${!this.doc?.querySelector( - ':root > Substation, :root > Line, :root > Process' - ) - ? html`

- this.openCreateSubstationWizard()} - > -

` - : html``}`; - } - - static styles = css` - mwc-fab { - position: fixed; - bottom: 32px; - right: 32px; - } - - :host { - width: 100vw; - } - `; -} diff --git a/packages/plugins/src/editors/Templates.ts b/packages/plugins/src/editors/Templates.ts deleted file mode 100644 index c24d50b862..0000000000 --- a/packages/plugins/src/editors/Templates.ts +++ /dev/null @@ -1,357 +0,0 @@ -import { LitElement, html, TemplateResult, property, css } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-fab'; -import '@material/mwc-icon-button'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - identity, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; - -import { - createElement, -} from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { styles } from './templates/foundation.js'; - -import { - createEnumTypeWizard, - eNumTypeEditWizard, -} from './templates/enumtype-wizard.js'; -import { - createDATypeWizard, - editDaTypeWizard, -} from './templates/datype-wizards.js'; -import { - createDOTypeWizard, - dOTypeWizard, -} from './templates/dotype-wizards.js'; -import { - createLNodeTypeWizard, - lNodeTypeWizard, -} from './templates/lnodetype-wizard.js'; - -import { List } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; - -const templates = fetch('public/xml/templates.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - -const nsd74 = fetch('public/xml/IEC_61850-7-4_2007B3.nsd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - -const nsd7420 = fetch('public/xml/IEC_61850-7-420_2019A4.nsd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - -/** An editor [[`plugin`]] for editing the `DataTypeTemplates` section. */ -export default class TemplatesPlugin extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - async openCreateLNodeTypeWizard(): Promise { - this.createDataTypeTemplates(); - - this.dispatchEvent( - newWizardEvent( - createLNodeTypeWizard( - this.doc.querySelector(':root > DataTypeTemplates')!, - await templates, - await nsd74, - await nsd7420 - ) - ) - ); - } - - openLNodeTypeWizard(identity: string): void { - const wizard = lNodeTypeWizard(identity, this.doc); - if (wizard) - this.dispatchEvent( - newWizardEvent(() => lNodeTypeWizard(identity, this.doc)!) - ); - } - - async openCreateDOTypeWizard(): Promise { - this.createDataTypeTemplates(); - - this.dispatchEvent( - newWizardEvent( - createDOTypeWizard( - this.doc.querySelector(':root > DataTypeTemplates')!, - await templates - ) - ) - ); - } - - openDOTypeWizard(identity: string): void { - const wizard = dOTypeWizard(identity, this.doc); - if (wizard) - this.dispatchEvent( - newWizardEvent(() => dOTypeWizard(identity, this.doc)!) - ); - } - - openDATypeWizard(identity: string): void { - const wizard = editDaTypeWizard(identity, this.doc); - if (wizard) - this.dispatchEvent( - newWizardEvent(() => editDaTypeWizard(identity, this.doc)!) - ); - } - - async openCreateDATypeWizard(): Promise { - this.createDataTypeTemplates(); - - this.dispatchEvent( - newWizardEvent( - createDATypeWizard( - this.doc.querySelector(':root > DataTypeTemplates')!, - await templates - ) - ) - ); - } - - openEnumTypeWizard(identity: string): void { - const wizard = eNumTypeEditWizard(identity, this.doc); - if (wizard) - this.dispatchEvent( - newWizardEvent(() => eNumTypeEditWizard(identity, this.doc)!) - ); - } - - async openCreateEnumWizard(): Promise { - this.createDataTypeTemplates(); - - this.dispatchEvent( - newWizardEvent( - createEnumTypeWizard( - this.doc.querySelector(':root > DataTypeTemplates')!, - await templates - ) - ) - ); - } - - createDataTypeTemplates(): void { - if (!this.doc.querySelector(':root > DataTypeTemplates')) - this.dispatchEvent( - newActionEvent({ - new: { - parent: this.doc.documentElement, - element: createElement(this.doc, 'DataTypeTemplates', {}), - }, - }) - ); - } - - render(): TemplateResult { - if (!this.doc?.querySelector(':root > DataTypeTemplates')) - return html`

- ${get('templates.missing')} - this.createDataTypeTemplates()} - > -

`; - return html` -
-
-

- ${get('scl.LNodeType')} - -

- - this.openLNodeTypeWizard( - ((e.target).selected).value - )} - > - ${Array.from( - this.doc.querySelectorAll( - ':root > DataTypeTemplates > LNodeType' - ) ?? [] - ).map( - lnodetype => - html`${lnodetype.getAttribute('id')}${lnodetype.getAttribute( - 'lnClass' - )}${lnodetype.querySelectorAll('DO').length}` - )} - -
-
-

- ${get('scl.DOType')} - -

- - this.openDOTypeWizard( - ((e.target).selected).value - )} - > - ${Array.from( - this.doc.querySelectorAll(':root > DataTypeTemplates > DOType') ?? - [] - ).map( - dotype => - html`${dotype.getAttribute('id')}${dotype.getAttribute( - 'cdc' - )}${dotype.querySelectorAll('SDO, DA').length}` - )} - -
-
-

- ${get('scl.DAType')} - -

- - this.openDATypeWizard( - ((e.target).selected).value - )} - > - ${Array.from( - this.doc.querySelectorAll(':root > DataTypeTemplates > DAType') ?? - [] - ).map( - datype => - html`${datype.getAttribute('id')}${datype.querySelectorAll('BDA').length}` - )} - -
-
-

- ${get('scl.EnumType')} - -

- - this.openEnumTypeWizard( - ((e.target).selected).value - )} - > - ${Array.from( - this.doc.querySelectorAll( - ':root > DataTypeTemplates > EnumType' - ) ?? [] - ).map( - enumtype => - html`${enumtype.getAttribute('id')}${enumtype.querySelectorAll('EnumVal').length}` - )} - -
-
- `; - } - - static styles = css` - ${styles} - - mwc-fab { - position: fixed; - bottom: 32px; - right: 32px; - } - - :host { - width: 100vw; - } - - #containerTemplates { - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - @media (max-width: 387px) { - #containerTemplates { - grid-template-columns: repeat(auto-fit, minmax(196px, auto)); - } - } - `; -} diff --git a/packages/plugins/src/editors/cleanup/control-blocks-container.ts b/packages/plugins/src/editors/cleanup/control-blocks-container.ts deleted file mode 100644 index 5bab88f383..0000000000 --- a/packages/plugins/src/editors/cleanup/control-blocks-container.ts +++ /dev/null @@ -1,430 +0,0 @@ -'use strict'; - -import { - customElement, - css, - html, - LitElement, - property, - TemplateResult, - query, - queryAll, -} from 'lit-element'; -import { classMap } from 'lit-html/directives/class-map'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-icon'; -import '@material/mwc-icon-button-toggle'; -import '@material/mwc-list/mwc-check-list-item.js'; -import '@material/mwc-checkbox'; - -import { Button } from '@material/mwc-button'; -import { Checkbox } from '@material/mwc-checkbox'; -import { List, MWCListIndex } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item.js'; - -import '@openscd/open-scd/src/filtered-list.js'; - -import { - identity, - isPublic, - newSubWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { Delete, newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { styles } from '../templates/foundation.js'; -import { - controlBlockIcons, - getFilterIcon, - iconType, -} from '@openscd/open-scd/src/icons/icons.js'; -import { editGseControlWizard, getGSE } from '../../wizards/gsecontrol.js'; -import { editReportControlWizard } from '../../wizards/reportcontrol.js'; -import { - editSampledValueControlWizard, - getSMV, -} from '../../wizards/sampledvaluecontrol.js'; -import { cleanSCLItems, identitySort } from './foundation.js'; - -type controlType = - | 'GSEControl' - | 'LogControl' - | 'SampledValueControl' - | 'ReportControl'; - -const iconMapping = { - GSEControl: 'gooseIcon', - LogControl: 'logIcon', - SampledValueControl: 'smvIcon', - ReportControl: 'reportIcon', -}; - -/** - * Check whether a control block is instantiated in the Communication section of the SCL file. - * @param controlBlock - SCL control block element. - * @returns true or false if a GSE or SMV element exists under the Communication section. - */ -function getCommAddress(controlBlock: Element): Element | null | undefined { - if (controlBlock.tagName === 'GSEControl') { - return getGSE(controlBlock); - } else if (controlBlock.tagName === 'SampledValueControl') { - return getSMV(controlBlock); - } - return null; -} - -/** An editor component for cleaning SCL Control Blocks. */ -@customElement('cleanup-control-blocks') -export class CleanupControlBlocks extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - - @property({ type: Boolean }) - disableControlClean = false; - - @property({ type: Array }) - unreferencedControls: Element[] = []; - - @property({ attribute: false }) - selectedControlItems: MWCListIndex | [] = []; - - @query('.deleteButton') - cleanButton!: Button; - - @query('.cleanupList') - cleanupList: List | undefined; - - @queryAll('mwc-check-list-item.cleanupListItem') - cleanupListItems: ListItem[] | undefined; - - @query('.cleanupAddressCheckbox') - cleanupAddressCheckbox: Checkbox | undefined; - - @query('.tGSEControlFilter') - cleanupGSEControlFilter!: Button; - - @query('.tSampledValueControlFilter') - cleanupSampledValueControlFilter!: Button; - - @query('.tLogControlFilter') - cleanupLogControlFilter!: Button; - - @query('.tReportControlFilter') - cleanupReportControlFilter!: Button; - - /** - * Toggle the class hidden in the unused controls list for use by filter buttons. - * @param selectorType - class for selection to toggle the hidden class used by the list. - */ - private toggleHiddenClass(selectorType: string) { - this.cleanupList!.querySelectorAll(`.${selectorType}`).forEach(element => { - element.classList.toggle('hiddenontypefilter'); - if (element.hasAttribute('disabled')) element.removeAttribute('disabled'); - else element.setAttribute('disabled', 'true'); - }); - } - - /** - * Initial update after container is loaded. - */ - async firstUpdated(): Promise { - this.cleanupList?.addEventListener('selected', () => { - this.selectedControlItems = this.cleanupList!.index; - }); - this.toggleHiddenClass('tReportControl'); - } - - /** - * Create a button for filtering in the control block cleanup container. - * @param controlType - SCL Control Type e.g. GSEControl. - * @param initialState - boolean representing whether button is on or off. - * @returns html for the icon button. - */ - private renderFilterIconButton( - controlType: controlType, - initialState = true - ): TemplateResult { - return html`${getFilterIcon(iconMapping[controlType], true)} - ${getFilterIcon(iconMapping[controlType], false)} - `; - } - - /** - * Provide list item in the control block cleanup container. - * @param controlBlock - an unused SCL ControlBlock element. - * @returns html for checklist item. - */ - private renderListItem(controlBlock: Element): TemplateResult { - return html`${controlBlock.getAttribute('name')!} - - - - - - - { - e.stopPropagation(); - if (controlBlock.tagName === 'GSEControl') { - e.target?.dispatchEvent( - newSubWizardEvent(editGseControlWizard(controlBlock)) - ); - } else if (controlBlock.tagName === 'ReportControl') { - e.target?.dispatchEvent( - newSubWizardEvent(editReportControlWizard(controlBlock)) - ); - } else if (controlBlock.tagName === 'SampledValueControl') { - e.target?.dispatchEvent( - newSubWizardEvent(editSampledValueControlWizard(controlBlock)) - ); - } else if (controlBlock.tagName === 'LogControl') { - // not implemented yet, disabled above - } - }} - > - - ${controlBlock.tagName} - - ${controlBlock.closest('IED')?.getAttribute('name')} - (${controlBlock.closest('IED')?.getAttribute('manufacturer') ?? - 'No manufacturer defined'}) - - - ${controlBlock.closest('IED')?.getAttribute('type') ?? - 'No Type Defined'} - ${controlBlockIcons[controlBlock.tagName]} - `; - } - - /** - * Provide delete button the control block cleanup container. - * @returns html for the Delete Button of this container. - */ - private renderDeleteButton(): TemplateResult { - const sizeSelectedItems = (>this.selectedControlItems).size; - - return html`>this.selectedControlItems).size === 0 || - (Array.isArray(this.selectedControlItems) && - !this.selectedControlItems.length)} - @click=${(e: MouseEvent) => { - const cleanItems = Array.from( - (>this.selectedControlItems).values() - ).map(index => this.unreferencedControls[index]); - let gseSmvAddressItems: Delete[] = []; - if (this.cleanupAddressCheckbox!.checked === true) { - // TODO: To be truly complete other elements should also be checked, possibly - // including: tServiceSettings, tReportSettings, tGSESettings, tSMVSettings - gseSmvAddressItems = cleanSCLItems( - cleanItems.map(cb => getCommAddress(cb)!).filter(Boolean) - ); - } - const gseSmvLogReportDeleteActions = - cleanSCLItems(cleanItems).concat(gseSmvAddressItems); - gseSmvLogReportDeleteActions.forEach(deleteAction => - e.target?.dispatchEvent(newActionEvent(deleteAction)) - ); - this.cleanupListItems!.forEach(item => { - item.selected = false; - }); - }} - >`; - } - - /** - * Render a user selectable table of unreferenced datasets if any exist, otherwise indicate this is not an issue. - * @returns html for table and action button. - */ - private renderUnreferencedControls() { - const unreferencedCBs: Element[] = []; - // Control Blocks which can have a DataSet reference - Array.from( - this.doc?.querySelectorAll( - 'GSEControl, ReportControl, SampledValueControl, LogControl' - ) ?? [] - ) - .filter(isPublic) - .forEach(cb => { - const parent = cb.parentElement; - const name = cb.getAttribute('datSet'); - const isReferenced = parent?.querySelector(`DataSet[name="${name}"]`); - if (parent && (!name || !isReferenced)) unreferencedCBs.push(cb); - }); - this.unreferencedControls = identitySort(unreferencedCBs); - return html` -
-

- ${get('cleanup.unreferencedControls.title')} - (${unreferencedCBs.length}) - - - - -

- ${this.renderFilterIconButton('LogControl')} - ${this.renderFilterIconButton('ReportControl', false)} - ${this.renderFilterIconButton('GSEControl')} - ${this.renderFilterIconButton('SampledValueControl')} - ${Array.from(unreferencedCBs.map(cb => this.renderListItem(cb)))} - -
-
- ${this.renderDeleteButton()} - - >this.selectedControlItems).size === 0 || - (Array.isArray(this.selectedControlItems) && - !this.selectedControlItems.length)} - > -
- `; - } - - render(): TemplateResult { - return html` -
${this.renderUnreferencedControls()}
- `; - } - - static styles = css` - ${styles} - - section { - display: flex; - flex: 1; - flex-direction: column; - justify-content: space-between; - } - - @media (max-width: 1200px) { - footer { - flex-direction: row; - } - - mwc-check-list-item { - overflow: hidden; - text-overflow: ellipsis; - } - } - - .editItem, - .cautionItem { - --mdc-icon-size: 16px; - } - - .editItem { - visibility: hidden; - opacity: 0; - } - - .cleanupListItem:hover .editItem { - visibility: visible; - opacity: 1; - transition: visibility 0s, opacity 0.5s linear; - } - - .cautionItem { - color: var(--yellow); - } - - .cautionItem[disabled], - .editItem[disabled] { - display: none; - } - - .deleteButton { - float: right; - } - - footer { - align-items: center; - align-content: center; - display: flex; - flex-flow: row wrap; - flex-direction: row-reverse; - justify-content: space-between; - margin: 16px; - } - - filtered-list { - min-height: 20vh; - overflow-y: scroll; - } - - .tGSEControlFilter[on], - .tSampledValueControlFilter[on], - .tLogControlFilter[on], - .tReportControlFilter[on] { - color: var(--secondary); - opacity: 1; - } - - /* Make sure to type filter here - .hidden is set on string filter in filtered-list and must always filter*/ - .cleanupListItem.hiddenontypefilter:not(.hidden) { - display: none; - } - - /* filter disabled, Material Design guidelines for opacity */ - .tGSEControlFilter, - .tSampledValueControlFilter, - .tLogControlFilter, - .tReportControlFilter { - opacity: 0.38; - } - `; -} diff --git a/packages/plugins/src/editors/cleanup/datasets-container.ts b/packages/plugins/src/editors/cleanup/datasets-container.ts deleted file mode 100644 index 4e7985504d..0000000000 --- a/packages/plugins/src/editors/cleanup/datasets-container.ts +++ /dev/null @@ -1,245 +0,0 @@ -'use strict'; - -import { - customElement, - css, - html, - LitElement, - property, - TemplateResult, - query, - queryAll, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-icon'; -import '@material/mwc-icon-button-toggle'; -import '@material/mwc-list/mwc-check-list-item.js'; -import '@material/mwc-checkbox'; - -import { Button } from '@material/mwc-button'; -import { List, MWCListIndex } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item.js'; - -import '@openscd/open-scd/src/filtered-list.js'; - -import { editDataSetWizard } from '../../wizards/dataset.js'; -import { styles } from '../templates/foundation.js'; -import { - identity, - isPublic, - newSubWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { cleanSCLItems, identitySort } from './foundation.js'; - -/** An editor component for cleaning SCL datasets. */ -@customElement('cleanup-datasets') -export class CleanupDatasets extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - - @property({ type: Boolean }) - disableDataSetClean = false; - - @property({ type: Array }) - unreferencedDataSets: Element[] = []; - - @property({ attribute: false }) - selectedDatasetItems: MWCListIndex | [] = []; - - @query('.deleteButton') - cleanupButton!: Button; - - @query('.dataSetList') - dataSetList: List | undefined; - - @queryAll('mwc-check-list-item.checkListItem') - dataSetItems: ListItem[] | undefined; - - async firstUpdated(): Promise { - this.dataSetList?.addEventListener('selected', () => { - this.selectedDatasetItems = this.dataSetList!.index; - }); - } - - /** - * Provide list item in the DataSet cleanup container. - * @param dataSet - an unused SCL DataSet element. - * @returns html for checklist item. - */ - private renderListItem(dataSet: Element): TemplateResult { - return html` ${dataSet.getAttribute('name')!} - - - { - e.stopPropagation(); - e.target?.dispatchEvent( - newSubWizardEvent(() => editDataSetWizard(dataSet)) - ); - }} - > - - ${dataSet.closest('IED')?.getAttribute('name')} - (${dataSet.closest('IED')?.getAttribute('manufacturer') ?? - 'No manufacturer defined'}) - - - ${dataSet.closest('IED')?.getAttribute('type') ?? - 'No Type Defined'} - `; - } - - /** - * Provide delete button the dataset cleanup container. - * @returns html for the Delete Button of this container. - */ - private renderDeleteButton(): TemplateResult { - const sizeSelectedItems = (>this.selectedDatasetItems).size; - - return html` >this.selectedDatasetItems).size === 0 || - (Array.isArray(this.selectedDatasetItems) && - !this.selectedDatasetItems.length)} - @click=${(e: MouseEvent) => { - const cleanItems = Array.from( - (>this.selectedDatasetItems).values() - ).map(index => this.unreferencedDataSets[index]); - const deleteActions = cleanSCLItems(cleanItems); - deleteActions.forEach(deleteAction => - e.target?.dispatchEvent(newActionEvent(deleteAction)) - ); - this.dataSetItems!.forEach(item => { - item.selected = false; - }); - }} - >`; - } - - /** - * Render a user selectable table of unreferenced datasets if any exist, otherwise indicate this is not an issue. - * @returns html for table and action button. - */ - private renderUnreferencedDataSets(): TemplateResult { - const unreferencedDataSets: Element[] = []; - Array.from(this.doc?.querySelectorAll('DataSet') ?? []) - .filter(isPublic) - .forEach(dataSet => { - const parent = dataSet.parentElement; - const name = dataSet.getAttribute('name'); - const isReferenced = Array.from( - parent?.querySelectorAll( - 'GSEControl, ReportControl, SampledValueControl, LogControl' - ) ?? [] - ).some(cb => cb.getAttribute('datSet') === name); - - if (parent && (!name || !isReferenced)) - unreferencedDataSets.push(dataSet); - }); - this.unreferencedDataSets = identitySort(unreferencedDataSets); - return html` -
-

- ${get('cleanup.unreferencedDataSets.title')} - (${unreferencedDataSets.length}) - - - - -

- ${Array.from( - this.unreferencedDataSets.map( - item => html`${this.renderListItem(item)}` - ) - )} - -
-
${this.renderDeleteButton()}
- `; - } - - render(): TemplateResult { - return html` -
${this.renderUnreferencedDataSets()}
- `; - } - - static styles = css` - ${styles} - - section { - flex: 1; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - @media (max-width: 1200px) { - footer { - flex-direction: row; - } - - mwc-check-list-item { - overflow: hidden; - text-overflow: ellipsis; - } - } - - .editItem { - --mdc-icon-size: 16px; - } - - .editItem { - visibility: hidden; - opacity: 0; - } - - .checkListItem:hover .editItem { - visibility: visible; - opacity: 1; - transition: visibility 0s, opacity 0.5s linear; - } - - .cleanupDeleteButton { - float: right; - } - - footer { - margin: 16px; - display: flex; - flex-flow: row wrap; - flex-direction: row-reverse; - justify-content: space-between; - align-items: center; - align-content: center; - } - - filtered-list { - max-height: 70vh; - min-height: 20vh; - overflow-y: scroll; - } - `; -} diff --git a/packages/plugins/src/editors/cleanup/datatypes-container.ts b/packages/plugins/src/editors/cleanup/datatypes-container.ts deleted file mode 100644 index ce2aaec900..0000000000 --- a/packages/plugins/src/editors/cleanup/datatypes-container.ts +++ /dev/null @@ -1,591 +0,0 @@ -'use strict'; - -import { - customElement, - css, - html, - LitElement, - property, - TemplateResult, - query, - queryAll, -} from 'lit-element'; -import { classMap } from 'lit-html/directives/class-map'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-icon'; -import '@material/mwc-icon-button-toggle'; -import '@material/mwc-list/mwc-check-list-item.js'; -import '@material/mwc-checkbox'; - -import { Button } from '@material/mwc-button'; -import { Checkbox } from '@material/mwc-checkbox'; -import { List, MWCListIndex } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item.js'; - -import '@openscd/open-scd/src/filtered-list.js'; - -import { - identity, - isPublic, - newSubWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history.js'; - -import { styles } from '../templates/foundation.js'; -import { - dataTypeTemplateIcons, - getFilterIcon, - iconType, -} from '@openscd/open-scd/src/icons/icons.js'; - -import { lNodeTypeWizard } from '../templates/lnodetype-wizard.js'; -import { editDaTypeWizard } from '../templates/datype-wizards.js'; -import { dOTypeWizard } from '../templates/dotype-wizards.js'; -import { eNumTypeEditWizard } from '../templates/enumtype-wizard.js'; - -import { cleanSCLItems, identitySort, uniq } from './foundation.js'; - -type templateType = 'EnumType' | 'DAType' | 'DOType' | 'LNodeType'; - -const iconMapping = { - EnumType: 'enumIcon', - DAType: 'dAIcon', - DOType: 'dOIcon', - LNodeType: 'lNIcon', -}; - -const filterClassMapping: Record = { - EnumType: 'enum-type', - DAType: 'da-type', - DOType: 'do-type', - LNodeType: 'lnode-type', -}; - -/** An editor component for cleaning SCL DataType templates. */ -@customElement('cleanup-data-types') -export class CleanupDataTypes extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - - @property({ type: Boolean }) - disableControlClean = false; - - @property({ type: Array }) - unreferencedDataTypes: Element[] = []; - - @property({ attribute: false }) - selectedDataTypeItems: MWCListIndex | [] = []; - - @query('.delete-button') - cleanButton!: Button; - - @query('.cleanup-list') - cleanupList: List | undefined; - - @queryAll('mwc-check-list-item.cleanup-list-item') - cleanupListItems: ListItem[] | undefined; - - @query('.clean-sub-types-checkbox') - cleanSubTypesCheckbox: Checkbox | undefined; - - @query('.t-da-type-filter') - cleanupDATypeFilter!: Button; - - @query('.t-enum-type-filter') - cleanupEnumTypeFilter!: Button; - - @query('.t-lnode-type-filter') - cleanupLNodeTypeFilter!: Button; - - @query('.t-do-type-filter') - cleanupDOTypeFilter!: Button; - - /** - * Initial update after container is loaded. - */ - async firstUpdated(): Promise { - this.cleanupList?.addEventListener('selected', () => { - this.selectedDataTypeItems = this.cleanupList!.index; - }); - } - - /** - * Toggle the class hidden in the unused data type list for use by filter buttons to ensure selection works correctly. - * @param selectorType - class for selection to toggle the hidden class used by the list. - */ - private toggleHiddenClass(selectorType: string) { - this.cleanupList!.querySelectorAll(`.${selectorType}`).forEach(element => { - element.classList.toggle('hiddenontypefilter'); - if (element.hasAttribute('disabled')) element.removeAttribute('disabled'); - else element.setAttribute('disabled', 'true'); - }); - } - - /** - * Create a button for filtering in the data type cleanup container. - * @param dataType - SCL Data Type e.g. DOType. - * @param initialState - boolean representing whether button is on or off. - * @returns html for the icon button. - */ - private renderFilterIconButton( - dataType: templateType, - initialState = true - ): TemplateResult { - return html` { - this.toggleHiddenClass(`t-${filterClassMapping[dataType]}`); - }} - >${getFilterIcon(iconMapping[dataType], true)} - ${getFilterIcon(iconMapping[dataType], false)} - `; - } - - /** - * Opens an editor for a given data type. - * @param dType - SCL datatype element. - */ - private openDataTypeEditor(dType: Element) { - if (dType.tagName === 'LNodeType') { - this.dispatchEvent( - newSubWizardEvent(lNodeTypeWizard(identity(dType), this.doc)) - ); - } else if (dType.tagName === 'DAType') { - this.dispatchEvent( - newSubWizardEvent(editDaTypeWizard(identity(dType), this.doc)) - ); - } else if (dType.tagName === 'DOType') { - this.dispatchEvent( - newSubWizardEvent(dOTypeWizard(identity(dType), this.doc)) - ); - } else if (dType.tagName === 'EnumType') { - this.dispatchEvent( - newSubWizardEvent(eNumTypeEditWizard(identity(dType), this.doc)) - ); - } - } - - /** - * Return secondary descriptive parameter for a data type. - * @param dType - SCL datatype element. - * @returns string with secondary descriptive parameter for a data type - */ - private getDataTypeSecondaryText(dType: Element): string | null | undefined { - if (dType.tagName === 'LNodeType') { - return dType.getAttribute('lnClass'); - } else if (dType.tagName === 'DAType') { - return dType.getAttribute('desc'); - } else if (dType.tagName === 'DOType') { - return dType.getAttribute('cdc'); - } else if (dType.tagName === 'EnumType') { - return dType.getAttribute('desc'); - } - return 'Unknown'; - } - - /** - * Provide list item in the data type cleanup container. - * @param dType - an unused SCL DataType element (LNodeType, DOType, DAType EnumType). - * @returns html for checklist item. - */ - private renderListItem(dType: Element): TemplateResult { - return html`${dType.getAttribute('id')!} - - - - ${this.getDataTypeSecondaryText(dType)} - ${dataTypeTemplateIcons[dType.tagName]} - `; - } - - /** - * Recurses through all datatype templates and indexes their usage. - * @returns a map of data type templates usage by id. - */ - private indexDataTypeTemplates(dttStart: Element[]) { - const dataTypeFrequencyUsage = new Map(); - - // recursively fetch all usages - const allUsages = this.fetchTree(dttStart); - - // make frequency count of datatype ids - allUsages.forEach(item => { - dataTypeFrequencyUsage.set( - item, - (dataTypeFrequencyUsage.get(item) || 0) + 1 - ); - }); - return dataTypeFrequencyUsage; - } - - /** - * Given a datatype reference return the appropriate datatype object or null. - * @param element - the SCL Element for which a datatype is required. - * @returns either the datatype or null. - */ - private getSubType(element: Element): Element | null { - const dataTypeTemplates = this.doc.querySelector( - ':root > DataTypeTemplates' - ); - const type = element.getAttribute('type'); - if (element.tagName === 'DO' || element.tagName === 'SDO') { - return dataTypeTemplates!.querySelector(`DOType[id="${type}"]`); - } else if ( - (element.tagName === 'DA' || element.tagName === 'BDA') && - element.getAttribute('bType') === 'Struct' - ) { - return dataTypeTemplates!.querySelector(`DAType[id="${type}"]`); - } else if ( - (element.tagName === 'DA' || element.tagName === 'BDA') && - element.getAttribute('bType') === 'Enum' - ) { - return dataTypeTemplates!.querySelector(`EnumType[id="${type}"]`); - } - return null; - } - - /** - * Recurses from an initial element to find all child references (with duplicates). - * @param rootElement - root SCL Element for which all child datatype references are required. - * @returns the id value for all SCL element datatypes traversed. - */ - private fetchTree(rootElements: Element[]): string[] { - const elementStack = [...rootElements]; - const traversedElements: string[] = []; - - // A max stack depth is defined to avoid recursive references. - const MAX_STACK_DEPTH = 300000; - - while (elementStack.length > 0 && elementStack.length <= MAX_STACK_DEPTH) { - const currentElement = elementStack.pop(); - traversedElements.push(currentElement!.getAttribute('id')!); - - const selector = 'DO, SDO, DA, BDA'; - - Array.from(currentElement!.querySelectorAll(selector)) - .filter(isPublic) - .forEach(element => { - const newElement = this.getSubType(element); - if (newElement !== null) { - elementStack.unshift(newElement); - } - }); - - if (elementStack.length >= MAX_STACK_DEPTH) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('cleanup.unreferencedDataTypes.title'), - message: get('cleanup.unreferencedDataTypes.stackExceeded', { - maxStackDepth: MAX_STACK_DEPTH.toString(), - }), - }) - ); - } - } - - return traversedElements; - } - - /** - * Get items from selection list and and any subtypes. - * @returns An array of SCL elements representing selected items and subtypes as required. - */ - public getCleanItems(): Element[] { - const cleanItems = Array.from( - (>this.selectedDataTypeItems).values() - ).map(index => this.unreferencedDataTypes[index]); - - if (this.cleanSubTypesCheckbox!.checked === true) { - const dataTypeTemplates = this.doc.querySelector( - ':root > DataTypeTemplates' - )!; - - const startingLNodeTypes = Array.from( - dataTypeTemplates.querySelectorAll('LNodeType') - ); - const dataTypeUsageCounter = - this.indexDataTypeTemplates(startingLNodeTypes); - - /* Create usage counter for children of LNodeTypes that are used. - We remember that _all_ valid template usages within a project - stem from LNodeTypes. */ - cleanItems.forEach(item => { - if (item.tagName === 'LNodeType') { - const childDataTypeTemplateIds = this.fetchTree([item]); - childDataTypeTemplateIds.forEach(id => { - dataTypeUsageCounter?.set(id, dataTypeUsageCounter.get(id)! - 1); - }); - } - }); - - /* Check to see if children of unused DOType, DAType are present - If so then unless they are from a data type which is part of - the main usage counter they can be safely removed. - If they are part of the main usage counter, then this does not - need to be considered as these DOType and DAType elements are - dangling, they're usage is not relevant. */ - cleanItems.forEach(item => { - if (['DOType', 'DAType'].includes(item.tagName)) { - const unusedDataTypeTemplateChildrenIds = uniq( - this.fetchTree([item]) - ); - unusedDataTypeTemplateChildrenIds.forEach(id => { - if (dataTypeUsageCounter.get(id) === undefined) - cleanItems.push(dataTypeTemplates.querySelector(`[id="${id}"]`)!); - }); - } - }); - - /* Now go through our usage index. If usage is zero then we can - remove the data type template safely. */ - dataTypeUsageCounter?.forEach((count, dataTypeId) => { - if (count <= 0) { - cleanItems.push( - dataTypeTemplates.querySelector(`[id="${dataTypeId}"]`)! - ); - } - }); - } - return cleanItems; - } - - /** - * Provide delete button the data type cleanup container. - * @returns html for the Delete Button of this container. - */ - private renderDeleteButton(): TemplateResult { - return html`>this.selectedDataTypeItems).size === 0 || - (Array.isArray(this.selectedDataTypeItems) && - !this.selectedDataTypeItems.length)} - @click=${() => { - const dataTypeItemsDeleteActions = cleanSCLItems(this.getCleanItems()); - dataTypeItemsDeleteActions.forEach(deleteAction => - this.dispatchEvent(newActionEvent(deleteAction)) - ); - this.cleanupListItems!.forEach(item => { - item.selected = false; - }); - }} - >`; - } - - /** - * Find unused types by scanning the SCL and comparing with the DataTypeTemplates. - * @param usedSelector - CSS selector for SCL type's instantiated name, e.g. LN, LN0. - * @param keyAttributeName - attribute name for SCL types uniqueness guarantee, e.g. lnType. - * @param templateSelector - CSS selector for SCL template element in DataTypeTemplate section. - * @returns an array of unreferenced elements sorted by their identity string. - */ - private getUnusedType( - usedSelector: string, - keyAttributeName: string, - templateSelector: string - ) { - const usedTypes = uniq( - Array.from(this.doc?.querySelectorAll(usedSelector) ?? []) - .filter(isPublic) - .map(uType => uType.getAttribute(keyAttributeName)) - ); - - const unreferencedTypes: Element[] = []; - Array.from( - this.doc?.querySelectorAll(`DataTypeTemplates > ${templateSelector}`) ?? - [] - ) - .filter(isPublic) - .forEach(dType => { - if (!usedTypes.includes(dType.getAttribute('id') ?? 'Unknown')) - unreferencedTypes.push(dType); - }); - return identitySort(unreferencedTypes); - } - - /** - * Find unused types by scanning the SCL and comparing with the DataTypeTemplates. - * @returns an array of unreferenced elements - */ - private getUnusedTypes() { - const unreferencedLNTypes = this.getUnusedType( - 'LN, LN0', - 'lnType', - 'LNodeType' - ); - const unreferencedDOTypes = this.getUnusedType('DO, SDO', 'type', 'DOType'); - const unreferencedDATypes = this.getUnusedType( - 'DA[bType="Struct"], BDA[bType="Struct"]', - 'type', - 'DAType' - ); - const unreferencedEnumTypes = this.getUnusedType( - 'DA[bType="Enum"], BDA[bType="Enum"]', - 'type', - 'EnumType' - ); - return unreferencedLNTypes.concat( - unreferencedDOTypes, - unreferencedDATypes, - unreferencedEnumTypes - ); - } - - /** - * Render a user selectable table of unreferenced DataTypes if any exist. - * @returns html for table and action button. - */ - private renderUnreferencedDataTypes() { - this.unreferencedDataTypes = this.getUnusedTypes(); - - return html` -
-

- ${get('cleanup.unreferencedDataTypes.title')} - (${this.unreferencedDataTypes.length}) - - - - -

- ${this.renderFilterIconButton('LNodeType')} - ${this.renderFilterIconButton('DOType')} - ${this.renderFilterIconButton('DAType')} - ${this.renderFilterIconButton('EnumType')} - ${Array.from( - this.unreferencedDataTypes.map(type => this.renderListItem(type)) - )} - -
-
- ${this.renderDeleteButton()} - - -
- `; - } - - render(): TemplateResult { - return html` -
${this.renderUnreferencedDataTypes()}
- `; - } - - static styles = css` - ${styles} - - section { - display: flex; - flex: 1; - flex-direction: column; - justify-content: space-between; - } - - @media (max-width: 1200px) { - footer { - flex-direction: row; - } - - mwc-check-list-item { - overflow: hidden; - text-overflow: ellipsis; - } - } - - .edit-item { - --mdc-icon-size: 16px; - visibility: hidden; - opacity: 0; - } - - .cleanup-list-item:hover .edit-item { - visibility: visible; - opacity: 1; - transition: visibility 0s, opacity 0.5s linear; - } - - .edit-item[disabled] { - display: none; - } - - .delete-button { - float: right; - } - - footer { - align-items: center; - align-content: center; - display: flex; - flex-flow: row wrap; - flex-direction: row-reverse; - justify-content: space-between; - margin: 16px; - } - - filtered-list { - min-height: 20vh; - overflow-y: scroll; - } - - /* filter itself changes colour after click */ - .t-da-type-filter[on], - .t-enum-type-filter[on], - .t-lnode-type-filter[on], - .t-do-type-filter[on] { - color: var(--secondary); - opacity: 1; - } - - /* Make sure to type filter here - .hidden is set on string filter in filtered-list and must always filter*/ - .cleanup-list-item.hiddenontypefilter:not(.hidden) { - display: none; - } - - /* filter disabled, Material Design guidelines for opacity */ - .t-da-type-filter, - .t-enum-type-filter, - .t-lnode-type-filter, - .t-do-type-filter { - opacity: 0.38; - } - `; -} diff --git a/packages/plugins/src/editors/cleanup/foundation.ts b/packages/plugins/src/editors/cleanup/foundation.ts deleted file mode 100644 index 4aac403cf8..0000000000 --- a/packages/plugins/src/editors/cleanup/foundation.ts +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -import { identity } from '@openscd/open-scd/src/foundation.js'; -import { Delete } from '@openscd/core/foundation/deprecated/editor.js'; - -/** - * Clean SCL items as requested by removing SCL elements specified from the SCL file - * @param cleanItems - SCL elements to be removed from the SCL file - * @returns an actions array to support undo/redo - */ -export function cleanSCLItems(cleanItems: Element[]): Delete[] { - const actions: Delete[] = []; - if (cleanItems) { - cleanItems.forEach(item => { - actions.push({ - old: { - parent: item.parentElement!, - element: item, - reference: item!.nextSibling, - }, - }); - }); - } - return actions; -} - -/** - * Provide frequency count of elements. - * @param arr - An array of elements - * @returns a Map of element strings and frequencies - */ -export function countBy(arr: string[]): Map { - return arr.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); -} - -/** - * Sort a list of Elements by their identity string. - * @param elements - an array of Elements. - * @returns a sorted list of elements. - */ -export function identitySort(elements: Element[]): Element[] { - return elements.sort((a: Element, b: Element) => { - // sorting using the identity ensures sort order includes IED and other useful properties - const aId = identity(a); - const bId = identity(b); - if (aId < bId) { - return -1; - } - if (aId > bId) { - return 1; - } - // names must be equal - return 0; - }); -} - -/** - * Return a de-duplicate set of array elements. - * @param arr - an array of items with duplicates. - * @returns an array of items without duplicates. - */ -export function uniq(arr: unknown[]): unknown[] { - return Array.from(new Set(arr)); -} diff --git a/packages/plugins/src/editors/communication/connectedap-editor.ts b/packages/plugins/src/editors/communication/connectedap-editor.ts deleted file mode 100644 index 84296c56db..0000000000 --- a/packages/plugins/src/editors/communication/connectedap-editor.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - LitElement, - TemplateResult, - customElement, - html, - property, -} from 'lit-element'; - -import '@material/mwc-fab'; - -import '@openscd/open-scd/src/action-icon.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { editConnectedApWizard } from '../../wizards/connectedap.js'; - -/** [[`Communication`]] subeditor for a `ConnectedAP` element. */ -@customElement('connectedap-editor') -export class ConnectedAPEditor extends LitElement { - /** SCL element ConnectedAP */ - @property({ attribute: false }) - element!: Element; - /** ConnectedAP attribute apName */ - @property({ type: String }) - get apName(): string { - return this.element.getAttribute('apName') ?? 'UNDEFINED'; - } - - private openEditWizard(): void { - this.dispatchEvent(newWizardEvent(editConnectedApWizard(this.element))); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - render(): TemplateResult { - return html` - - - `; - } -} diff --git a/packages/plugins/src/editors/communication/gse-editor.ts b/packages/plugins/src/editors/communication/gse-editor.ts deleted file mode 100644 index 54dbcc37ca..0000000000 --- a/packages/plugins/src/editors/communication/gse-editor.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - LitElement, - TemplateResult, - html, - customElement, - property, - state, -} from 'lit-element'; - -import '@material/mwc-icon'; - -import '@openscd/open-scd/src/action-icon.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { sizableGooseIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { editGseWizard } from '../../wizards/gse.js'; - -@customElement('gse-editor') -export class GseEditor extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - - @property({ attribute: false }) - element!: Element; - - @state() - get label(): string { - return ( - this.element.getAttribute('ldInst') + - '/' + - this.element.getAttribute('cbName') - ); - } - - private openEditWizard(): void { - this.dispatchEvent(newWizardEvent(editGseWizard(this.element))); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - render(): TemplateResult { - return html` - `; - } -} diff --git a/packages/plugins/src/editors/communication/smv-editor.ts b/packages/plugins/src/editors/communication/smv-editor.ts deleted file mode 100644 index 18966f24b9..0000000000 --- a/packages/plugins/src/editors/communication/smv-editor.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - LitElement, - TemplateResult, - html, - customElement, - property, - state, -} from 'lit-element'; - -import '@material/mwc-icon'; - -import '@openscd/open-scd/src/action-icon.js'; -import { sizableSmvIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { editSMvWizard } from '../../wizards/smv.js'; - -@customElement('smv-editor') -export class SmvEditor extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - - @property({ attribute: false }) - element!: Element; - - @state() - get label(): string { - return ( - this.element.getAttribute('ldInst') + - '/' + - this.element.getAttribute('cbName') - ); - } - - private openEditWizard(): void { - this.dispatchEvent(newWizardEvent(editSMvWizard(this.element))); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - render(): TemplateResult { - return html` - `; - } -} diff --git a/packages/plugins/src/editors/communication/subnetwork-editor.ts b/packages/plugins/src/editors/communication/subnetwork-editor.ts deleted file mode 100644 index 40c5efde8a..0000000000 --- a/packages/plugins/src/editors/communication/subnetwork-editor.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { - LitElement, - TemplateResult, - customElement, - html, - property, - css, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button'; - -import './connectedap-editor.js'; -import './gse-editor.js'; -import './smv-editor.js'; -import { - newWizardEvent, - compareNames, -} from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { createConnectedApWizard } from '../../wizards/connectedap.js'; -import { wizards } from '../../wizards/wizard-library.js'; - -/** [[`Communication`]] subeditor for a `SubNetwork` element. */ -@customElement('subnetwork-editor') -export class SubNetworkEditor extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - /** SCL element SubNetwork */ - @property({ attribute: false }) - element!: Element; - /** SubNetwork attribute name */ - @property({ type: String }) - get name(): string { - return this.element.getAttribute('name') ?? 'UNDEFINED'; - } - /** SubNetwork attribute desc */ - @property({ type: String }) - get desc(): string | null { - return this.element.getAttribute('desc') ?? null; - } - /** SubNetwork attribute type */ - @property({ type: String }) - get type(): string | null { - return this.element.getAttribute('type') ?? null; - } - /** SubNetwork child elements BitRate label */ - @property({ type: String }) - get bitrate(): string | null { - const bitRate = this.element.querySelector('BitRate'); - if (bitRate === null) return null; - const bitRateValue = bitRate.textContent ?? ''; - const m = bitRate.getAttribute('multiplier'); - const unit = ` ${m ?? ''}b/s`; - return bitRateValue ? bitRateValue + unit : null; - } - - private openConnectedAPwizard(): void { - this.dispatchEvent(newWizardEvent(createConnectedApWizard(this.element))); - } - - private openEditWizard(): void { - const wizard = wizards['SubNetwork'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - private renderSmvEditors(iedName: string): TemplateResult[] { - return Array.from( - this.element - .closest('Communication') - ?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > SMV`) ?? [] - ).map( - smv => html`` - ); - } - - private renderGseEditors(iedName: string): TemplateResult[] { - return Array.from( - this.element - .closest('Communication') - ?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > GSE`) ?? [] - ).map( - gse => html`` - ); - } - - private renderConnectedApEditors(iedName: string): TemplateResult[] { - return Array.from( - this.element.parentElement?.querySelectorAll( - `:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]` - ) ?? [] - ).map( - connectedAP => - html`` - ); - } - - private renderIEDs(): TemplateResult[] { - return Array.from(this.element.querySelectorAll(':scope > ConnectedAP')) - .map(connAP => connAP.getAttribute('iedName')!) - .filter((v, i, a) => a.indexOf(v) === i) - .sort(compareNames) - .map( - iedName => html` - ${this.renderConnectedApEditors(iedName)}${this.renderGseEditors( - iedName - )}${this.renderSmvEditors(iedName)} - ` - ); - } - - private subNetworkSpecs(): string { - if (!this.type && !this.bitrate) return ''; - - return `(${[this.type, this.bitrate].filter(text => !!text).join(' — ')})`; - } - - private header(): string { - return `${this.name} ${this.desc === null ? '' : `— ${this.desc}`} - ${this.subNetworkSpecs()}`; - } - - render(): TemplateResult { - return html` - - this.openEditWizard()} - > - - - this.remove()} - > - - - - -
${this.renderIEDs()}
-
`; - } - - static styles = css` - #iedContainer { - display: grid; - box-sizing: border-box; - gap: 12px; - padding: 8px 12px 16px; - grid-template-columns: repeat(auto-fit, minmax(150px, auto)); - } - - #iedSection:not(:focus):not(:focus-within) .disabled { - display: none; - } - - #iedSection:not(:focus):not(:focus-within) gse-editor { - display: none; - } - - #iedSection:not(:focus):not(:focus-within) smv-editor { - display: none; - } - - #iedSection .disabled { - pointer-events: none; - opacity: 0.5; - } - - abbr { - text-decoration: none; - border-bottom: none; - } - `; -} diff --git a/packages/plugins/src/editors/ied/access-point-container.ts b/packages/plugins/src/editors/ied/access-point-container.ts deleted file mode 100644 index 88be47fdc9..0000000000 --- a/packages/plugins/src/editors/ied/access-point-container.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { - css, - customElement, - html, - property, - PropertyValues, - state, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import { - getDescriptionAttribute, - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { accessPointIcon } from '@openscd/open-scd/src/icons/ied-icons.js'; -import { editServicesWizard } from '../../wizards/services.js'; - -import '@openscd/open-scd/src/action-pane.js'; -import './server-container.js'; - -import { Container } from './foundation.js'; - -/** [[`IED`]] plugin subeditor for editing `AccessPoint` element. */ -@customElement('access-point-container') -export class AccessPointContainer extends Container { - @property() - selectedLNClasses: string[] = []; - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When the LN Classes filter is updated, we also want to trigger rendering for the LN Elements. - if (_changedProperties.has('selectedLNClasses')) { - this.requestUpdate('lnElements'); - } - } - - private renderServicesIcon(): TemplateResult { - const services: Element | null = this.element.querySelector('Services'); - - if (!services) { - return html``; - } - - return html` - this.openSettingsWizard(services)} - > - `; - } - - private openSettingsWizard(services: Element): void { - const wizard = editServicesWizard(services); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - @state() - private get lnElements(): Element[] { - return Array.from(this.element.querySelectorAll(':scope > LN')).filter( - element => { - const lnClass = element.getAttribute('lnClass') ?? ''; - return this.selectedLNClasses.includes(lnClass); - } - ); - } - - private header(): TemplateResult { - const name = getNameAttribute(this.element); - const desc = getDescriptionAttribute(this.element); - - return html`${name}${desc ? html` — ${desc}` : nothing}`; - } - - render(): TemplateResult { - const lnElements = this.lnElements; - - return html` - ${accessPointIcon} - ${this.renderServicesIcon()} - ${Array.from(this.element.querySelectorAll(':scope > Server')).map( - server => - html`` - )} -
- ${lnElements.map( - ln => html`` - )} -
-
`; - } - - static styles = css` - #lnContainer { - display: grid; - grid-gap: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - @media (max-width: 387px) { - #lnContainer { - grid-template-columns: repeat(auto-fit, minmax(196px, auto)); - } - } - `; -} diff --git a/packages/plugins/src/editors/ied/da-container.ts b/packages/plugins/src/editors/ied/da-container.ts deleted file mode 100644 index 14df87d121..0000000000 --- a/packages/plugins/src/editors/ied/da-container.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { - css, - customElement, - html, - property, - query, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button-toggle'; -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import '@openscd/open-scd/src/action-pane.js'; -import { - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { wizards } from '../../wizards/wizard-library.js'; -import { - DaiFieldTypes, - getCustomField, -} from '../../wizards/foundation/dai-field-type.js'; -import { createDaInfoWizard } from './da-wizard.js'; -import { - Container, - getInstanceDAElement, - getValueElements, -} from './foundation.js'; -import { createDAIWizard } from '../../wizards/dai.js'; -import { - determineUninitializedStructure, - initializeElements, -} from '@openscd/open-scd/src/foundation/dai.js'; - -/** [[`IED`]] plugin subeditor for editing `(B)DA` element. */ -@customElement('da-container') -export class DAContainer extends Container { - /** - * The optional DAI of this (B)DA. - */ - @property({ attribute: false }) - instanceElement!: Element; - - @query('#toggleButton') - toggleButton: IconButtonToggle | undefined; - - private header(): TemplateResult { - const name = getNameAttribute(this.element); - const bType = this.element.getAttribute('bType') ?? nothing; - const fc = this.element.getAttribute('fc'); - - if (this.instanceElement) { - return html`${name} — ${bType}${fc ? html` [${fc}]` : ``}`; - } else { - return html`${name} — ${bType}${fc ? html` [${fc}]` : ``}`; - } - } - - /** - * Get the nested (B)DA element(s) if available. - * @returns The nested (B)DA element(s) of this (B)DA container. - */ - private getBDAElements(): Element[] { - const type = this.element!.getAttribute('type') ?? undefined; - const doType = this.element!.closest('SCL')!.querySelector( - `:root > DataTypeTemplates > DAType[id="${type}"]` - ); - if (doType != null) { - return Array.from(doType!.querySelectorAll(':scope > BDA')); - } - return []; - } - - /** - * Use the list of ancestor to retrieve the list from DO to the current (B)DA Element. - * This structure is used to create the initialized structure from (DOI/SDI/DAI). - * - * @returns The list from the DO Element to the current (B)DA Element. - */ - private getTemplateStructure(): Element[] { - // Search for the DO Element, this will be the starting point. - const doElement = this.ancestors.filter( - element => element.tagName == 'DO' - )[0]; - // From the DO Element and below we need all the elements (BDA, SDO, DA) - const dataStructure = this.ancestors.slice( - this.ancestors.indexOf(doElement) - ); - // Add the current DA Element also to the list. - dataStructure.push(this.element); - return dataStructure; - } - - private openCreateWizard(): void { - // Search the LN(0) Element to start creating the initialized structure. - const lnElement = this.ancestors.filter(element => - ['LN0', 'LN'].includes(element.tagName) - )[0]; - const templateStructure = this.getTemplateStructure(); - // First determine where to start creating new elements (DOI/SDI/DAI) - const [parentElement, uninitializedTemplateStructure] = - determineUninitializedStructure(lnElement, templateStructure); - // Next create all missing elements (DOI/SDI/DAI) - const newElement = initializeElements(uninitializedTemplateStructure); - - if (newElement) { - const wizard = createDAIWizard(parentElement, newElement, this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - } - - private openEditWizard(val: Element): void { - const wizard = wizards['DAI'].edit(this.element, val); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private getValueDisplayString(val: Element): string { - const sGroup = val.getAttribute('sGroup'); - const prefix = sGroup ? `SG${sGroup}: ` : ''; - const value = val.textContent?.trim(); - - return `${prefix}${value}`; - } - - private renderVal(): TemplateResult[] { - const bType = this.element!.getAttribute('bType'); - const element = this.instanceElement ?? this.element; - const hasInstantiatedVal = !!this.instanceElement?.querySelector('Val'); - - return hasInstantiatedVal - ? getValueElements(element).map( - val => html`
-
-

${this.getValueDisplayString(val)}

-
-
- this.openEditWizard(val)} - > - -
-
` - ) - : [ - html`
-
-

-
-
- this.openCreateWizard()} - > - -
-
`, - ]; - } - - render(): TemplateResult { - const bType = this.element!.getAttribute('bType'); - - return html` - - - - this.dispatchEvent( - newWizardEvent( - createDaInfoWizard( - this.element, - this.instanceElement, - this.ancestors, - this.nsdoc - ) - ) - )} - > - - ${bType === 'Struct' - ? html` - this.requestUpdate()} - > - - ` - : html`${this.renderVal()}`} - ${this.toggleButton?.on && bType === 'Struct' - ? this.getBDAElements().map( - bdaElement => - html` - ` - ) - : nothing} - - `; - } - - static styles = css` - h4 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - margin: 0px; - padding-left: 0.3em; - word-break: break-word; - white-space: pre-wrap; - } - - mwc-icon-button { - color: var(--mdc-theme-on-surface); - } - `; -} diff --git a/packages/plugins/src/editors/ied/da-wizard.ts b/packages/plugins/src/editors/ied/da-wizard.ts deleted file mode 100644 index 2f8b486229..0000000000 --- a/packages/plugins/src/editors/ied/da-wizard.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { html } from 'lit-element'; -import { TemplateResult } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-textarea'; -import '@material/mwc-textfield'; - -import { - getDescriptionAttribute, - getInstanceAttribute, - getNameAttribute, - Wizard, -} from '@openscd/open-scd/src/foundation.js'; -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; -import { - findDOTypeElement, - findElement, - findLogicaNodeElement, - getValueElements, -} from './foundation.js'; - -function getValues(element: Element): string { - const hasValue = getValueElements(element).length !== 0; - - return hasValue - ? `${getValueElements(element) - .map(val => val.textContent ?? '') - .join(', ')}` - : '-'; -} - -function renderFields( - element: Element, - instanceElement: Element | undefined, - ancestors: Element[], - nsdoc: Nsdoc -): TemplateResult[] { - const iedElement = findElement(ancestors, 'IED'); - const accessPointElement = findElement(ancestors, 'AccessPoint'); - const lDeviceElement = findElement(ancestors, 'LDevice'); - const logicalNodeElement = findLogicaNodeElement(ancestors); - const doElement = findElement(ancestors, 'DO'); - const doTypeElement = findDOTypeElement(doElement); - - return [ - html` - - - `, - html` - - - `, - html` - - - `, - html` - - - `, - html` - - - `, - html` - - - `, - html`
`, - html` - - - `, - html` - - - `, - html`
`, - html` - - - `, - html` - - - `, - html` - - - `, - html`
`, - html` - - - `, - html` - - - `, - html` - - - `, - ]; -} - -export function createDaInfoWizard( - element: Element, - instanceElement: Element | undefined, - ancestors: Element[], - nsdoc: Nsdoc -): Wizard { - return [ - { - title: get('iededitor.wizard.daTitle'), - content: [...renderFields(element, instanceElement, ancestors, nsdoc)], - }, - ]; -} diff --git a/packages/plugins/src/editors/ied/do-container.ts b/packages/plugins/src/editors/ied/do-container.ts deleted file mode 100644 index 9ae583f12f..0000000000 --- a/packages/plugins/src/editors/ied/do-container.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { - customElement, - html, - property, - query, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button-toggle'; -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import '@openscd/open-scd/src/action-pane.js'; -import './da-container.js'; - -import { - getDescriptionAttribute, - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { createDoInfoWizard } from './do-wizard.js'; -import { - Container, - findDOTypeElement, - getInstanceDAElement, -} from './foundation.js'; - -/** [[`IED`]] plugin subeditor for editing `DO` element. */ -@customElement('do-container') -export class DOContainer extends Container { - /** - * The optional DOI of this DO. - */ - @property({ attribute: false }) - instanceElement!: Element; - - @query('#toggleButton') toggleButton: IconButtonToggle | undefined; - - private header(): TemplateResult { - const name = getNameAttribute(this.element); - const desc = getDescriptionAttribute(this.element); - - if (this.instanceElement != null) { - return html`${name}${desc ? html` — ${desc}` : nothing}`; - } else { - return html`${name}${desc ? html` — ${desc}` : nothing}`; - } - } - - /** - * Get the nested SDO element(s). - * @returns The nested SDO element(s) of this DO container. - */ - private getDOElements(): Element[] { - const doType = findDOTypeElement(this.element); - if (doType != null) { - return Array.from(doType.querySelectorAll(':scope > SDO')); - } - return []; - } - - /** - * Get the nested (B)DA element(s). - * @returns The nested (B)DA element(s) of this DO container. - */ - private getDAElements(): Element[] { - const type = this.element.getAttribute('type') ?? undefined; - const doType = this.element - .closest('SCL')! - .querySelector(`:root > DataTypeTemplates > DOType[id="${type}"]`); - if (doType != null) { - return Array.from(doType!.querySelectorAll(':scope > DA')); - } - return []; - } - - /** - * Get the instance element (SDI) of a (S)DO element (if available) - * @param dO - The (S)DO object to search with. - * @returns The optional SDI element. - */ - private getInstanceDOElement(dO: Element): Element | null { - const sdoName = getNameAttribute(dO); - if (this.instanceElement) { - return this.instanceElement.querySelector( - `:scope > SDI[name="${sdoName}"]` - ); - } - return null; - } - - render(): TemplateResult { - const daElements = this.getDAElements(); - const doElements = this.getDOElements(); - - return html` - - - this.dispatchEvent( - newWizardEvent( - createDoInfoWizard( - this.element, - this.instanceElement, - this.ancestors, - this.nsdoc - ) - ) - )} - > - - ${daElements.length > 0 || doElements.length > 0 - ? html` - this.requestUpdate()} - > - ` - : nothing} - ${this.toggleButton?.on - ? daElements.map( - daElement => - html`` - ) - : nothing} - ${this.toggleButton?.on - ? doElements.map( - doElement => - html`` - ) - : nothing} - `; - } -} diff --git a/packages/plugins/src/editors/ied/do-wizard.ts b/packages/plugins/src/editors/ied/do-wizard.ts deleted file mode 100644 index d2e07f05d4..0000000000 --- a/packages/plugins/src/editors/ied/do-wizard.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { html } from 'lit-element'; -import { TemplateResult } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-textarea'; -import '@material/mwc-textfield'; - -import { - getDescriptionAttribute, - getInstanceAttribute, - getNameAttribute, - Wizard, -} from '@openscd/open-scd/src/foundation.js'; -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; -import { - findDOTypeElement, - findElement, - findLogicaNodeElement, -} from './foundation.js'; - -function renderFields( - element: Element, - instanceElement: Element | undefined, - ancestors: Element[], - nsdoc: Nsdoc -): TemplateResult[] { - const iedElement = findElement(ancestors, 'IED'); - const accessPointElement = findElement(ancestors, 'AccessPoint'); - const lDeviceElement = findElement(ancestors, 'LDevice'); - const logicalNodeElement = findLogicaNodeElement(ancestors); - const doTypeElement = findDOTypeElement(element); - - return [ - html` - - - `, - html` - - - `, - html` - - - `, - html` - - - `, - html`
`, - html` - - - `, - html` - - - `, - html` - - - `, - html`
`, - html` - - - `, - html` - - - `, - html` - - - `, - ]; -} - -export function createDoInfoWizard( - element: Element, - instanceElement: Element | undefined, - ancestors: Element[], - nsdoc: Nsdoc -): Wizard { - return [ - { - title: get('iededitor.wizard.doTitle'), - content: [...renderFields(element, instanceElement, ancestors, nsdoc)], - }, - ]; -} diff --git a/packages/plugins/src/editors/ied/element-path.ts b/packages/plugins/src/editors/ied/element-path.ts deleted file mode 100644 index 09c0bec96e..0000000000 --- a/packages/plugins/src/editors/ied/element-path.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - state, - TemplateResult, -} from 'lit-element'; -import { FullElementPathEvent } from './foundation.js'; - -@customElement('element-path') -export class ElementPath extends LitElement { - - @state() - elementNames: string[] = []; - - constructor() { - super(); - - const parentSection = this.closest('section'); - if (parentSection) { - parentSection.addEventListener('full-element-path', (event: FullElementPathEvent) => { - this.elementNames = event.detail.elementNames; - }); - } - } - - render(): TemplateResult { - return html` -

${this.elementNames.join(' / ')}

- `; - } - - static styles = css` - h3 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - transition: background-color 150ms linear; - }`; -} diff --git a/packages/plugins/src/editors/ied/foundation.ts b/packages/plugins/src/editors/ied/foundation.ts deleted file mode 100644 index c85048a756..0000000000 --- a/packages/plugins/src/editors/ied/foundation.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { LitElement, property } from 'lit-element'; - -import { - getInstanceAttribute, - getNameAttribute, -} from '@openscd/open-scd/src/foundation.js'; -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; - -/** Base class for all containers inside the IED Editor. */ -export class Container extends LitElement { - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @property({ attribute: false }) - element!: Element; - - @property() - nsdoc!: Nsdoc; - - @property() - ancestors: Element[] = []; - - constructor() { - super(); - - this.addEventListener('focus', event => { - event.stopPropagation(); - const pathOfAncestorNames = this.ancestors.map( - ancestor => getTitleForElementPath(ancestor)! - ); - pathOfAncestorNames.push(getTitleForElementPath(this.element)!); - - this.dispatchEvent(newFullElementPathEvent(pathOfAncestorNames)); - }); - - this.addEventListener('blur', () => { - this.dispatchEvent( - newFullElementPathEvent( - this.ancestors.map(ancestor => getTitleForElementPath(ancestor)!) - ) - ); - }); - } -} - -/** - * Search for an element with a passed tag-name in the list of ancestors passed. - * @param ancestors - The list of elements to search in for an LN or LN0 element. - * @param tagName - The Tag-name of the element to search for. - * @returns The found element with the tag-name or null if not found. - */ -export function findElement( - ancestors: Element[], - tagName: string -): Element | null { - return ancestors.find(element => element.tagName === tagName) ?? null; -} - -/** - * Search for the LN0 or LN element in the list of ancestors passed. - * @param ancestors - The list of elements to search in for an LN or LN0 element. - * @returns The LN0/LN Element found or null if not found. - */ -export function findLogicaNodeElement(ancestors: Element[]): Element | null { - let element = findElement(ancestors, 'LN0'); - if (!element) { - element = findElement(ancestors, 'LN'); - } - return element; -} - -/** - * With the passed DO Element retrieve the type attribute and search for the DOType in the DataType Templates section. - * @param element - The DO Element. - * @returns The DOType element found in the DataType Templates section or null if it not exists. - */ -export function findDOTypeElement(element: Element | null): Element | null { - if (element && element.hasAttribute('type')) { - const type = element.getAttribute('type'); - return element - .closest('SCL')! - .querySelector(`:root > DataTypeTemplates > DOType[id="${type}"]`); - } - return null; -} - -/** - * Get the instance element (SDI / DAI) of a DA element (if available) - * @param parentInstance - The parent instance if available to search in for other instance elements. - * @param da - The (B)DA object to search with. - * @returns The optional SDI / DAI element. - */ -export function getInstanceDAElement( - parentInstance: Element | null, - da: Element -): Element | null { - if (parentInstance) { - const daName = getNameAttribute(da); - const bType = da.getAttribute('bType'); - if (bType == 'Struct') { - return parentInstance.querySelector(`:scope > SDI[name="${daName}"]`); - } - return parentInstance.querySelector(`:scope > DAI[name="${daName}"]`); - } - return null; -} - -export function getTitleForElementPath(element: Element): string { - switch (element.tagName) { - case 'LN': - case 'LN0': { - return element.getAttribute('lnClass')!; - } - case 'LDevice': { - return (getNameAttribute(element) ?? getInstanceAttribute(element))!; - } - case 'Server': { - return 'Server'; - } - default: { - return element.getAttribute('name')!; - } - } -} - -/** @returns Array of 'Val' elements for a given parent data attribute */ -export function getValueElements(parent: Element): Element[] { - return Array.from(parent.querySelectorAll('Val')); -} - -export interface FullElementPathDetail { - elementNames: string[]; -} -export type FullElementPathEvent = CustomEvent; -export function newFullElementPathEvent( - elementNames: string[], - eventInitDict?: CustomEventInit -): FullElementPathEvent { - return new CustomEvent('full-element-path', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { elementNames, ...eventInitDict?.detail }, - }); -} - -declare global { - interface ElementEventMap { - ['full-element-path']: FullElementPathEvent; - } -} diff --git a/packages/plugins/src/editors/ied/ied-container.ts b/packages/plugins/src/editors/ied/ied-container.ts deleted file mode 100644 index 12134a61e5..0000000000 --- a/packages/plugins/src/editors/ied/ied-container.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - css, - customElement, - html, - property, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@openscd/open-scd/src/action-pane.js'; -import './access-point-container.js'; - -import { wizards } from '../../wizards/wizard-library.js'; -import { Container } from './foundation.js'; -import { - getDescriptionAttribute, - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { removeIEDWizard } from '../../wizards/ied.js'; -import { editServicesWizard } from '../../wizards/services.js'; - -/** [[`IED`]] plugin subeditor for editing `IED` element. */ -@customElement('ied-container') -export class IedContainer extends Container { - @property() - selectedLNClasses: string[] = []; - - private openEditWizard(): void { - const wizard = wizards['IED'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private renderServicesIcon(): TemplateResult { - const services: Element | null = this.element.querySelector('Services'); - - if (!services) { - return html``; - } - - return html` - this.openSettingsWizard(services)} - > - `; - } - - private openSettingsWizard(services: Element): void { - const wizard = editServicesWizard(services); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private removeIED(): void { - const wizard = removeIEDWizard(this.element); - if (wizard) { - this.dispatchEvent(newWizardEvent(() => wizard)); - } else { - // If no Wizard is needed, just remove the element. - this.dispatchEvent( - newActionEvent({ - old: { parent: this.element.parentElement!, element: this.element }, - }) - ); - } - } - - private header(): TemplateResult { - const name = getNameAttribute(this.element); - const desc = getDescriptionAttribute(this.element); - - return html`${name}${desc ? html` — ${desc}` : nothing}`; - } - - render(): TemplateResult { - return html` - developer_board - - this.removeIED()} - > - - - this.openEditWizard()} - > - - ${this.renderServicesIcon()} - ${Array.from(this.element.querySelectorAll(':scope > AccessPoint')).map( - ap => html`` - )} - `; - } - - static styles = css` - abbr { - text-decoration: none; - border-bottom: none; - } - `; -} diff --git a/packages/plugins/src/editors/ied/ldevice-container.ts b/packages/plugins/src/editors/ied/ldevice-container.ts deleted file mode 100644 index 2c9f97456d..0000000000 --- a/packages/plugins/src/editors/ied/ldevice-container.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { - css, - customElement, - html, - property, - PropertyValues, - query, - state, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import { - getDescriptionAttribute, - getInstanceAttribute, - getNameAttribute, - getLdNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { logicalDeviceIcon } from '@openscd/open-scd/src/icons/ied-icons.js'; - -import '@openscd/open-scd/src/action-pane.js'; -import './ln-container.js'; - -import { wizards } from '../../wizards/wizard-library.js'; -import { Container } from './foundation.js'; - -/** [[`IED`]] plugin subeditor for editing `LDevice` element. */ -@customElement('ldevice-container') -export class LDeviceContainer extends Container { - @property() - selectedLNClasses: string[] = []; - - @query('#toggleButton') - toggleButton!: IconButtonToggle | undefined; - - private openEditWizard(): void { - const wizard = wizards['LDevice'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private header(): TemplateResult { - const nameOrInst = - getNameAttribute(this.element) ?? getInstanceAttribute(this.element); - const desc = getDescriptionAttribute(this.element); - const ldName = getLdNameAttribute(this.element); - - return html`${nameOrInst}${desc ? html` — ${desc}` : nothing}${ldName - ? html` — ${ldName}` - : nothing}`; - } - - protected firstUpdated(): void { - this.requestUpdate(); - } - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When the LN Classes filter is updated, we also want to trigger rendering for the LN Elements. - if (_changedProperties.has('selectedLNClasses')) { - this.requestUpdate('lnElements'); - } - } - - @state() - private get lnElements(): Element[] { - return Array.from(this.element.querySelectorAll(':scope > LN,LN0')).filter( - element => { - const lnClass = element.getAttribute('lnClass') ?? ''; - return this.selectedLNClasses.includes(lnClass); - } - ); - } - - render(): TemplateResult { - const lnElements = this.lnElements; - - return html` - ${logicalDeviceIcon} - - this.openEditWizard()} - > - - ${lnElements.length > 0 - ? html` - this.requestUpdate()} - > - ` - : nothing} -
- ${this.toggleButton?.on - ? lnElements.map( - ln => html` ` - ) - : nothing} -
-
`; - } - - static styles = css` - #lnContainer { - display: grid; - grid-gap: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - abbr { - text-decoration: none; - } - - @media (max-width: 387px) { - #lnContainer { - grid-template-columns: repeat(auto-fit, minmax(196px, auto)); - } - } - `; -} diff --git a/packages/plugins/src/editors/ied/ln-container.ts b/packages/plugins/src/editors/ied/ln-container.ts deleted file mode 100644 index 190b65a295..0000000000 --- a/packages/plugins/src/editors/ied/ln-container.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { customElement, html, query, TemplateResult } from 'lit-element'; -import { nothing } from 'lit-html'; -import { until } from 'lit-html/directives/until'; -import { get } from 'lit-translate'; - -import { - getInstanceAttribute, - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import '@openscd/open-scd/src/action-pane.js'; -import './do-container.js'; - -import { Container } from './foundation.js'; -import { wizards } from '../../wizards/wizard-library.js'; - -/** [[`IED`]] plugin subeditor for editing `LN` and `LN0` element. */ -@customElement('ln-container') -export class LNContainer extends Container { - @query('#toggleButton') - toggleButton!: IconButtonToggle | undefined; - - private header(): TemplateResult { - const prefix = this.element.getAttribute('prefix'); - const inst = getInstanceAttribute(this.element); - const desc = this.element.getAttribute('desc'); - - const data = this.nsdoc.getDataDescription(this.element); - - return html`${prefix != null ? html`${prefix} — ` : nothing} - ${data.label} ${inst ? html` — ${inst}` : nothing} - ${desc ? html` — ${desc}` : nothing}`; - } - - /** - * Get the DO child elements of this LN(0) section. - * @returns The DO child elements, or an empty array if none are found. - */ - private getDOElements(): Element[] { - const lnType = this.element.getAttribute('lnType') ?? undefined; - const lNodeType = this.element - .closest('SCL')! - .querySelector(`:root > DataTypeTemplates > LNodeType[id="${lnType}"]`); - if (lNodeType != null) { - return Array.from(lNodeType.querySelectorAll(':scope > DO')); - } - return []; - } - - /** - * Get the instance element (DOI) of a DO element (if available) - * @param dO - The DO object to use. - * @returns The optional DOI object. - */ - private getInstanceElement(dO: Element): Element | null { - const doName = getNameAttribute(dO); - return this.element.querySelector(`:scope > DOI[name="${doName}"]`); - } - - private openEditWizard(): void { - const wizardType = this.element.tagName === 'LN' ? 'LN' : 'LN0'; - const wizard = wizards[wizardType].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - render(): TemplateResult { - const doElements = this.getDOElements(); - - return html` - ${doElements.length > 0 - ? html` - - - - this.requestUpdate()} - > - ` - : nothing} - ${this.toggleButton?.on - ? doElements.map( - dO => html` ` - ) - : nothing} - `; - } -} diff --git a/packages/plugins/src/editors/ied/server-container.ts b/packages/plugins/src/editors/ied/server-container.ts deleted file mode 100644 index 7568ddc545..0000000000 --- a/packages/plugins/src/editors/ied/server-container.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - customElement, - html, - property, - PropertyValues, - state, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; - -import '@openscd/open-scd/src/action-pane.js'; -import './ldevice-container.js'; -import { serverIcon } from '@openscd/open-scd/src/icons/ied-icons.js'; -import { getDescriptionAttribute } from '@openscd/open-scd/src/foundation.js'; -import { Container } from './foundation.js'; - -/** [[`IED`]] plugin subeditor for editing `Server` element. */ -@customElement('server-container') -export class ServerContainer extends Container { - @property() - selectedLNClasses: string[] = []; - - private header(): TemplateResult { - const desc = getDescriptionAttribute(this.element); - - return html`Server${desc ? html` — ${desc}` : nothing}`; - } - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When the LN Classes filter is updated, we also want to trigger rendering for the LN Elements. - if (_changedProperties.has('selectedLNClasses')) { - this.requestUpdate('lDeviceElements'); - } - } - - @state() - private get lDeviceElements(): Element[] { - return Array.from(this.element.querySelectorAll(':scope > LDevice')).filter( - element => { - return ( - Array.from(element.querySelectorAll(':scope > LN,LN0')).filter( - element => { - const lnClass = element.getAttribute('lnClass') ?? ''; - return this.selectedLNClasses.includes(lnClass); - } - ).length > 0 - ); - } - ); - } - - render(): TemplateResult { - return html` - ${serverIcon} - ${this.lDeviceElements.map( - server => - html`` - )} - `; - } -} diff --git a/packages/plugins/src/editors/protocol104/base-container.ts b/packages/plugins/src/editors/protocol104/base-container.ts deleted file mode 100644 index 8570e60dce..0000000000 --- a/packages/plugins/src/editors/protocol104/base-container.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LitElement, property } from 'lit-element'; - -export class Base104Container extends LitElement { - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; -} diff --git a/packages/plugins/src/editors/protocol104/connectedap-editor.ts b/packages/plugins/src/editors/protocol104/connectedap-editor.ts deleted file mode 100644 index 73b8e72dea..0000000000 --- a/packages/plugins/src/editors/protocol104/connectedap-editor.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { customElement, html, property, TemplateResult } from 'lit-element'; - -import '@material/mwc-fab'; - -import '@openscd/open-scd/src/action-icon.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { editConnectedApWizard } from './wizards/connectedap.js'; -import { Base104Container } from './base-container.js'; - -/** [[`104`]] subeditor for a `ConnectedAP` element. */ -@customElement('connectedap-104-editor') -export class ConnectedAP104Editor extends Base104Container { - /** SCL element ConnectedAP */ - @property({ attribute: false }) - element!: Element; - - private openEditWizard(): void { - this.dispatchEvent( - newWizardEvent(() => - editConnectedApWizard( - this.element, - this.element.querySelectorAll('Address > P[type^="RG"]').length > 0 - ) - ) - ); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - render(): TemplateResult { - return html` - - - `; - } -} diff --git a/packages/plugins/src/editors/protocol104/doi-container.ts b/packages/plugins/src/editors/protocol104/doi-container.ts deleted file mode 100644 index 5e10baaf21..0000000000 --- a/packages/plugins/src/editors/protocol104/doi-container.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { - css, - customElement, - html, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; -import { nothing } from 'lit-html'; - -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import '@material/mwc-icon'; -import '@material/mwc-icon-button'; -import '@material/mwc-icon-button-toggle'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; - -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; - -import '@openscd/open-scd/src/action-pane.js'; - -import { - get104DetailsLine, - getCdcValueFromDOIElement, - getFullPath, -} from './foundation/foundation.js'; -import { editAddressWizard } from './wizards/address.js'; -import { showDOIInfoWizard } from './wizards/doi.js'; -import { PROTOCOL_104_PRIVATE } from './foundation/private.js'; -import { Base104Container } from './base-container.js'; - -/** - * Container showing all the DAI Elements, related to the 104 Protocol, of the passed DOI Element in a list. - * The DAI Element can be edited by pressing the Edit button at the end of the line. - */ -@customElement('doi-104-container') -export class Doi104Container extends Base104Container { - @property() - element!: Element; - - @query('#toggleButton') - toggleButton!: IconButtonToggle | undefined; - - @property() - get daiElements(): Element[] { - return Array.from(this.element.querySelectorAll(`DAI`)) - .filter( - daiElement => - daiElement.querySelector( - `Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ) !== null - ) - .sort((dai1, dai2) => - getFullPath(dai1, 'DOI').localeCompare(getFullPath(dai2, 'DOI')) - ); - } - - private getAddressElements(daiElement: Element): Element[] { - return Array.from( - daiElement.querySelectorAll( - `Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ) - ).sort( - (addr1, addr2) => - (addr1.getAttribute('casdu') ?? '').localeCompare( - addr2.getAttribute('casdu') ?? '' - ) && - (addr1.getAttribute('ioa') ?? '').localeCompare( - addr2.getAttribute('ioa') ?? '' - ) - ); - } - - protected firstUpdated(): void { - this.requestUpdate(); - } - - private openEditAddressWizard( - daiElement: Element, - addressElement: Element - ): void { - const doiElement = daiElement.closest('DOI')!; - const iedElement = doiElement.closest('IED')!; - this.dispatchEvent( - newWizardEvent( - editAddressWizard(iedElement, doiElement, daiElement, addressElement) - ) - ); - } - - private openEditTiWizard(): void { - this.dispatchEvent(newWizardEvent(showDOIInfoWizard(this.element))); - } - - @property() - get header(): TemplateResult { - const fullPath = getFullPath(this.element, 'IED'); - const cdc = getCdcValueFromDOIElement(this.element); - - return html`${fullPath}${cdc ? html` (${cdc})` : nothing}`; - } - - private renderAddressList(daiElement: Element): TemplateResult { - const addresses = this.getAddressElements(daiElement); - return html`${addresses.map(addressElement => { - return html` - -   - ${get104DetailsLine(daiElement, addressElement)} - - - this.openEditAddressWizard(daiElement, addressElement)} - > - - - - `; - })}`; - } - - private renderDaiList(): TemplateResult { - const daiElements = this.daiElements; - return html`${daiElements.map(daiElement => { - return html` - - ${getFullPath(daiElement, 'DOI')} - - ${this.renderAddressList(daiElement)} - `; - })}`; - } - - render(): TemplateResult { - return html` - - - this.openEditTiWizard()} - > - - - this.requestUpdate()} - > - - - ${this.toggleButton?.on - ? html` ${this.renderDaiList()} ` - : nothing} - - `; - } - - static styles = css` - abbr { - text-decoration: none; - border-bottom: none; - } - - mwc-list-item { - --mdc-list-item-meta-size: 48px; - } - `; -} diff --git a/packages/plugins/src/editors/protocol104/foundation/actions.ts b/packages/plugins/src/editors/protocol104/foundation/actions.ts deleted file mode 100644 index f7f42078ef..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/actions.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Create } from '@openscd/core/foundation/deprecated/editor.js'; -import { TiInformation } from './cdc.js'; - -/** - * Create a list of Create Actions using the parameters passed. First search for the DAI Elements - * that can be effected. Next create the action and add it to this list, also start the Edit - * Address Element wizard for all Address Elements created. - * - * @param lnElement - The LN Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - The Wizard to dispatch the Open Wizard event on. - * @param ti - The TI Value set on the new Address Elements. - * @param inverted - Indicates if the Engineer want to create inverted Address Elements, if applicable. - * @param tiInformation - Information about how to create the Address Elements for the passed TI. - * @returns A list of Create Action that will be added to the complex action. - */ -export function createActions( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - inverted: boolean, - tiInformation: TiInformation -): Create[] { - return tiInformation.create( - lnElement, - lnClonedElement, - doElement, - wizard, - ti, - tiInformation.daPaths, - // If the TI Allows inverted and the Engineer selected it, true will be passed. - tiInformation.inverted ? inverted : false - ); -} - -/** - * Create a list of Create Actions using the parameters passed. First search for the DAI Elements [name="Check"]. - * Next create the action and add it to this list, also start the Edit Address Element wizard for all Address Elements - * created. - * - * @param lnElement - The LN Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - The Wizard to dispatch the Open Wizard event on. - * @param ti - The TI Value set on the new Address Elements. - * @param tiInformation - Information about how to create the Address Elements for the passed TI. - * @returns A list of Create Action that will be added to the complex action. - */ -export function createCheckActions( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - tiInformation: TiInformation -): Create[] { - if (tiInformation.checkDaPaths && tiInformation.checkCreate) { - return tiInformation.checkCreate( - lnElement, - lnClonedElement, - doElement, - wizard, - ti, - tiInformation.checkDaPaths - ); - } - return []; -} diff --git a/packages/plugins/src/editors/protocol104/foundation/cdc.ts b/packages/plugins/src/editors/protocol104/foundation/cdc.ts deleted file mode 100644 index 5a8256fd9a..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/cdc.ts +++ /dev/null @@ -1,971 +0,0 @@ -import { - getNameAttribute, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { Create } from '@openscd/core/foundation/deprecated/editor.js'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history.js'; - -import { - addPrefixAndNamespaceToDocument, - createPrivateAddress, - createPrivateElement, - getPrivateElement, -} from './private.js'; -import { - findElementInOriginalLNStructure, - getCdcValueFromDOElement, - getEnumOrds, - getTypeAttribute, - isEnumDataAttribute, -} from './foundation.js'; -import { editAddressWizard } from '../wizards/address.js'; -import { - determineUninitializedStructure, - initializeElements, -} from '@openscd/open-scd/src/foundation/dai.js'; -import { get } from 'lit-translate'; - -/** - * List of supported Common Data Classes in the 104 protocol. - */ -export const supportedCdcTypes = [ - 'ACD', - 'ACT', - 'APC', - 'ASG', - 'BAC', - 'BCR', - 'BSC', - 'CMV', - 'DEL', - 'DPC', - 'DPS', - 'ENC', - 'ENG', - 'ENS', - 'INC', - 'ING', - 'INS', - 'ISC', - 'MV', - 'SEC', - 'SPC', - 'SPG', - 'SPS', - 'WYE', -] as const; -export type SupportedCdcType = (typeof supportedCdcTypes)[number]; - -export type CreateFunction = ( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - daPaths: DaSelector[], - inverted: boolean -) => Create[]; -export type CreateCheckFunction = ( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - daPaths: DaSelector[] -) => Create[]; - -export interface DaSelector { - path: string[]; -} -export interface TiInformation { - daPaths: DaSelector[]; - create: CreateFunction; - checkDaPaths?: DaSelector[]; - checkCreate?: CreateCheckFunction; - inverted?: boolean; -} - -/** - * Record with configuration information on how to create Address elements for the 104 protocol. - * Per supported Common Data Class (CDC) two record sets can be configured, one for the monitoring part - * and one for the control part. - * Per set the key of the record will be the ti value, meaning the list of keys will be the supported - * ti values allowed for the CDC. - * For each supported ti value there is information on how to find the DAI Element to which to create - * the Address element(s). - */ -export const cdcProcessings: Record< - SupportedCdcType, - { - monitor: Record; - control: Record; - } -> = { - ACD: { - monitor: { - '30': { - daPaths: [ - { path: ['general'] }, - { path: ['phsA'] }, - { path: ['phsB'] }, - { path: ['phsC'] }, - { path: ['neut'] }, - ], - create: createAddressAction, - inverted: true, - }, - '40': { - daPaths: [ - { path: ['general'] }, - { path: ['phsA'] }, - { path: ['phsB'] }, - { path: ['phsC'] }, - { path: ['neut'] }, - ], - create: createAddressAction, - }, - }, - control: {}, - }, - ACT: { - monitor: { - '30': { - daPaths: [ - { path: ['general'] }, - { path: ['phsA'] }, - { path: ['phsB'] }, - { path: ['phsC'] }, - { path: ['neut'] }, - ], - create: createAddressAction, - inverted: true, - }, - '39': { - daPaths: [{ path: ['general'] }], - create: createAddressAction, - }, - }, - control: {}, - }, - APC: { - monitor: { - '36': { - daPaths: [{ path: ['mxVal', 'f'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '63': { - daPaths: [{ path: ['Oper', 'ctlVal', 'f'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - ASG: { - monitor: { - '63': { - daPaths: [{ path: ['setMag', 'f'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - BAC: { - monitor: { - '36': { - daPaths: [{ path: ['mxVal', 'f'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '60': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - BCR: { - monitor: { - '37': { - daPaths: [{ path: ['actVal'] }, { path: ['frVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - BSC: { - monitor: { - '32': { - daPaths: [{ path: ['valWTr', 'posVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '60': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - CMV: { - monitor: { - '35': { - daPaths: [{ path: ['mag', 'i'] }, { path: ['ang', 'i'] }], - create: createAddressAction, - inverted: true, - }, - '36': { - daPaths: [{ path: ['mag', 'f'] }, { path: ['ang', 'f'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - DEL: { - monitor: { - '35': { - daPaths: [ - { path: ['phsAB', 'cVal', 'mag', 'f'] }, - { path: ['phsBC', 'cVal', 'mag', 'f'] }, - { path: ['phsCA', 'cVal', 'mag', 'f'] }, - ], - create: createAddressAction, - inverted: false, - }, - '36': { - daPaths: [ - { path: ['phsAB', 'cVal', 'mag', 'f'] }, - { path: ['phsBC', 'cVal', 'mag', 'f'] }, - { path: ['phsCA', 'cVal', 'mag', 'f'] }, - ], - create: createAddressAction, - inverted: false, - }, - }, - control: {}, - }, - DPC: { - monitor: { - '31': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '59': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - DPS: { - monitor: { - '31': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - ENC: { - monitor: { - '30': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - '35': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: false, - }, - }, - control: { - '58': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressWithExpectValueAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - '62': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressWithExpectValueAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - ENG: { - monitor: { - '58': { - daPaths: [{ path: ['setVal'] }], - create: createAddressWithExpectValueAction, - inverted: true, - }, - '62': { - daPaths: [{ path: ['setVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - ENS: { - monitor: { - '30': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - '35': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - INC: { - monitor: { - '35': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '62': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - ING: { - monitor: { - '62': { - daPaths: [{ path: ['setVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - INS: { - monitor: { - '30': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - '33': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - '35': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - ISC: { - monitor: { - '32': { - daPaths: [{ path: ['valWTr', 'posVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '62': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - MV: { - monitor: { - '35': { - daPaths: [{ path: ['mag', 'i'] }], - create: createAddressAction, - inverted: true, - }, - '36': { - daPaths: [{ path: ['mag', 'f'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - SEC: { - monitor: { - '37': { - daPaths: [{ path: ['cnt'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - SPC: { - monitor: { - '30': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: { - '58': { - daPaths: [{ path: ['Oper', 'ctlVal'] }], - create: createAddressAction, - checkDaPaths: [{ path: ['Oper', 'Check'] }], - checkCreate: createCheckAddressAction, - }, - }, - }, - SPG: { - monitor: { - '58': { - daPaths: [{ path: ['setVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - SPS: { - monitor: { - '30': { - daPaths: [{ path: ['stVal'] }], - create: createAddressAction, - inverted: true, - }, - }, - control: {}, - }, - WYE: { - monitor: { - '35': { - daPaths: [ - { path: ['phsA', 'cVal', 'mag', 'f'] }, - { path: ['phsB', 'cVal', 'mag', 'f'] }, - { path: ['phsC', 'cVal', 'mag', 'f'] }, - ], - create: createAddressAction, - inverted: false, - }, - '36': { - daPaths: [ - { path: ['phsA', 'cVal', 'mag', 'f'] }, - { path: ['phsB', 'cVal', 'mag', 'f'] }, - { path: ['phsC', 'cVal', 'mag', 'f'] }, - ], - create: createAddressAction, - inverted: false, - }, - }, - control: {}, - }, -}; - -/** - * Creates a new SCL Private element and add 104 Address element(s) below this. - * Set the attribute value of 'ti' to the passed ti value. - * - * @param lnElement - The LN(0) Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - Wizard Element to dispatch events on. - * @param ti - The value to be set on the attribute 'ti'. - * @param daPaths - The Array of DAI Elements to search or create and add the Private Element on. - * @param inverted - Indicates if extra Address Elements should be created with 'inverted=true'. - * @returns An array of Create Action that the wizard action will return. - */ -function createAddressAction( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - daPaths: DaSelector[], - inverted: boolean -): Create[] { - const actions: Create[] = []; - - const [initializeActions, daiElements] = findOrCreateDaiElements( - lnElement, - lnClonedElement, - doElement, - wizard, - daPaths - ); - if (initializeActions.length > 0) { - actions.push(...initializeActions); - } - - if (daiElements.length > 0) { - addPrefixAndNamespaceToDocument(lnElement.ownerDocument); - - daiElements.forEach(daiElement => { - const addressElements = createAddressElements( - daiElement.ownerDocument, - ti, - inverted - ); - actions.push(...createActionsForPrivate(daiElement, addressElements)); - }); - } - - startEditWizards(wizard, lnElement, lnClonedElement, doElement, actions); - return actions; -} - -/** - * Creates a new SCL Private element and add 104 Address element(s) below this. - * Set the attribute value of 'ti' to the passed ti value. - * - * @param lnElement - The LN(0) Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - Wizard Element to dispatch events on. - * @param ti - The value to be set on the attribute 'ti'. - * @param daPaths - The Array of DAI Elements to search or create and add the Private Element on. - * @param inverted - Indicates if extra Address Elements should be created with 'inverted=true'. - * @returns An array of Create Action that the wizard action will return. - */ -function createAddressWithExpectValueAction( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - daPaths: DaSelector[], - inverted: boolean -): Create[] { - const actions: Create[] = []; - - const [initializeActions, daiElements] = findOrCreateDaiElements( - lnElement, - lnClonedElement, - doElement, - wizard, - daPaths - ); - if (initializeActions.length > 0) { - actions.push(...initializeActions); - } - if (daiElements.length > 0) { - addPrefixAndNamespaceToDocument(lnElement.ownerDocument); - - const addressElements: Element[] = []; - daiElements.forEach(daiElement => { - if (isEnumDataAttribute(daiElement)) { - getEnumOrds(daiElement).forEach(ord => - addressElements.push( - ...createAddressElements( - daiElement.ownerDocument, - ti, - inverted, - ord - ) - ) - ); - } else { - addressElements.push( - ...createAddressElements(daiElement.ownerDocument, ti, inverted) - ); - } - - actions.push(...createActionsForPrivate(daiElement, addressElements)); - }); - } - - startEditWizards(wizard, lnElement, lnClonedElement, doElement, actions); - return actions; -} - -/** - * Create a new SCL Private element and add 104 Address element(s) below this. - * Set the attribute value of 'ti' to the passed ti value. - * - * @param lnElement - The LN(0) Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - Wizard Element to dispatch events on. - * @param ti - The value to be set on the attribute 'ti'. - * @param daPaths - The Array of DAI Elements to search or create and add the Private Element on. - * @returns An array of Create Action that the wizard action will return. - */ -function createCheckAddressAction( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - ti: string, - daPaths: DaSelector[] -): Create[] { - const actions: Create[] = []; - - const [initializeActions, daiElements] = findOrCreateDaiElements( - lnElement, - lnClonedElement, - doElement, - wizard, - daPaths - ); - if (initializeActions.length > 0) { - actions.push(...initializeActions); - } - if (daiElements.length > 0) { - addPrefixAndNamespaceToDocument(lnElement.ownerDocument); - - daiElements.forEach(daiElement => { - const address1Element = createPrivateAddress( - daiElement.ownerDocument, - ti - ); - address1Element.setAttribute('check', 'interlocking'); - - const address2Element = createPrivateAddress( - daiElement.ownerDocument, - ti - ); - address2Element.setAttribute('check', 'synchrocheck'); - - actions.push( - ...createActionsForPrivate(daiElement, [ - address1Element, - address2Element, - ]) - ); - }); - } - - startEditWizards(wizard, lnElement, lnClonedElement, doElement, actions); - return actions; -} - -/** - * Create or update the 104 Private Element, if the Private already exists, the new Address Elements are - * added, otherwise a new Private Element is created to which the Address Elements are added. - * The correct Create Action is returned. - * - * @param daiElement - The DAI Element which will hold the new or existing Private Element - * @param addressElements - The Address Elements to be created with Create Actions. - */ -export function createActionsForPrivate( - daiElement: Element, - addressElements: Element[] -): Create[] { - const actions: Create[] = []; - let privateElement = getPrivateElement(daiElement); - if (privateElement) { - addressElements.forEach(addressElement => { - actions.push({ - new: { parent: privateElement!, element: addressElement }, - }); - }); - } else { - privateElement = createPrivateElement(daiElement.ownerDocument); - privateElement.append(...addressElements); - - actions.push({ new: { parent: daiElement, element: privateElement } }); - } - return actions; -} - -/** - * Creates one or two Address Elements, depending on the value of inverted. - * - * @param document - The Owner Document used to create the new Address Element with. - * @param ti - The value to be set on the attribute 'ti'. - * @param inverted - Indicates if extra Address Elements should be created with 'inverted=true'. - * @param expectedValue - The optional value of the attribute 'expectedValue' if needed. - * @returns Array of one or two Address Elements created. - */ -export function createAddressElements( - document: Document, - ti: string, - inverted: boolean, - expectedValue?: string -): Element[] { - const addressElements: Element[] = []; - const addressElement = createPrivateAddress(document, ti); - if (expectedValue) { - addressElement.setAttribute('expectedValue', expectedValue); - } - addressElements.push(addressElement); - - if (inverted) { - const addressElement = createPrivateAddress(document, ti); - addressElement.setAttribute('inverted', 'true'); - if (expectedValue) { - addressElement.setAttribute('expectedValue', expectedValue); - } - addressElements.push(addressElement); - } - return addressElements; -} - -/** - * Use all Create Action to determine which Address Elements are created and start an Edit Address Wizard - * for every Address Element found. - * - * @param wizard - The current Wizard used to dispatch the new Wizards on. - * @param lnElement - The LN Element used to search for specific parent elements. - * @param lnClonedElement - The cloned LN Element to search for child elements. - * @param doElement - The DO Element for which the Address Elements where created. - * @param actions - The list of all the Create Actions. - */ -function startEditWizards( - wizard: Element, - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - actions: Create[] -): void { - actions.forEach(createAction => { - // Loop over all Actions and collect all Address Elements in an Array. - const newElement = createAction.new.element; - let addressElements: Element[]; - if (newElement.tagName === 'Address') { - addressElements = [newElement]; - } else { - addressElements = Array.from(newElement.querySelectorAll('Address')); - } - const parentElement = createAction.new.parent; - const daiElement = parentElement.closest('DAI'); - if (daiElement) { - const iedElement = lnElement.closest('IED')!; - const doiElement = lnClonedElement.querySelector( - `:scope > DOI[name="${getNameAttribute(doElement)}"]` - )!; - - addressElements.forEach(addressElement => { - wizard.dispatchEvent( - newWizardEvent(() => - editAddressWizard( - iedElement, - doiElement, - daiElement, - addressElement - ) - ) - ); - }); - } - }); -} - -/** - * Use the DA Path configuration of a Common Data Class to search for all DO/BDA/DA Elements to create - * a structure for which DOI/SDI/DAI Elements should be created later. Null will be returned when an invalid - * Template Structure is described by the DA Path. - * - * @param doElement - The DO Element to start searching for DA/BDA Elements. - * @param daPath - The (B)DA Elements to find in the template structure. - * @returns List of Elements starting with the DO Element followed by one or more (B)DA Elements describing the structure. - */ -function createTemplateStructure( - doElement: Element, - daPath: DaSelector -): Element[] | null { - let templateStructure: Element[] | null = [doElement]; - - const doc = doElement.ownerDocument; - const doType = getTypeAttribute(doElement) ?? ''; - let typeElement = doc.querySelector(`DOType[id="${doType}"]`); - - daPath.path.forEach(name => { - // There should be a DOType or DAType set for the current element in the list. - if (!typeElement) { - templateStructure = null; - return; - } - const sdoElement = typeElement.querySelector( - `:scope > SDO[name="${name}"]` - ); - const sdoType = sdoElement?.getAttribute('type'); - - if (sdoType) typeElement = doc.querySelector(`DOType[id="${sdoType}"]`); - - const daElement = typeElement!.querySelector( - `:scope > DA[name="${name}"], :scope > BDA[name="${name}"]` - ); - // If there is no DA/BDA Element found the structure is incorrect, so just stop. - if (daElement === null && sdoElement === null) { - templateStructure = null; - return; - } - - templateStructure!.push(sdoElement ? sdoElement : daElement!); - - if (sdoElement) return; - - const bType = daElement!.getAttribute('bType') ?? ''; - if (bType === 'Struct') { - const type = getTypeAttribute(daElement!) ?? ''; - typeElement = doc.querySelector(`DAType[id="${type}"]`); - } else { - typeElement = null; - } - }); - return templateStructure; -} - -/** - * Search for existing DAI Elements below the DO Element matching the DA Paths passed or create the DAI Element - * if the DA Path doesn't exist yet. - * - * @param lnElement - The LN(0) Element. - * @param lnClonedElement - The Cloned LN Element, used to create new structure and determine which Create actions are needed. - * @param doElement - The DO Element. - * @param wizard - The current Wizard to dispatch Log Events, if needed. - * @param daPaths - The DA Structures for which the DAI Structure needs to be created below the DO Element. - */ -function findOrCreateDaiElements( - lnElement: Element, - lnClonedElement: Element, - doElement: Element, - wizard: Element, - daPaths: DaSelector[] -): [Create[], Element[]] { - const daiElements: Element[] = []; - const actions: Create[] = []; - - // Start searching and creating for each DA Path passed. - daPaths.forEach(daPath => { - const filter = createDaiFilter(doElement, daPath); - const foundDaiElements = lnClonedElement.querySelectorAll(filter); - if (foundDaiElements.length > 0) { - // Existing DAI Element found, so use that Element. - foundDaiElements.forEach(clonedDaiElement => { - const daiElement = findElementInOriginalLNStructure( - lnElement, - clonedDaiElement - ); - if (daiElement) { - daiElements.push(daiElement); - } else { - daiElements.push(clonedDaiElement); - } - }); - } else { - // DAI Element doesn't exist yet, so create the structure using the DA Path. - const templateStructure = createTemplateStructure(doElement, daPath); - if (templateStructure) { - const [parentClonedElement, uninitializedTemplateStructure] = - determineUninitializedStructure(lnClonedElement, templateStructure); - // Next create all missing elements (DOI/SDI/DOI) - const newElement = initializeElements(uninitializedTemplateStructure); - - // Always add it to the cloned LN Structure. - parentClonedElement.append(newElement); - - // Search if the parent already exists in the current LN Element Structure. - // If so we will add a new Create Action for it. - // If it is already there because one of the parents of the parent is used in a Create Action. - const parentElement = findElementInOriginalLNStructure( - lnElement, - parentClonedElement - ); - if (parentElement) { - actions.push({ new: { parent: parentElement, element: newElement } }); - } - - // Add new DAI Elements to the list to return. - if (newElement.tagName === 'DAI') { - daiElements.push(newElement); - } else { - const daiElement = newElement.querySelector('DAI')!; - daiElements.push(daiElement); - } - } else { - // The DA Path can't be mapped on the Template structure of the current document. - const cdc = getCdcValueFromDOElement(doElement) ?? ''; - const doType = getTypeAttribute(doElement) ?? ''; - wizard.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('protocol104.wizard.error.addAddressError', { - structure: daPath.path.join(' > '), - cdc, - doType, - }), - }) - ); - } - } - }); - return [actions, daiElements]; -} - -/** - * Use the DO Element and a DA Selector to create a CSS Query to search for a DAI Element - * below the LN Element. - * - * @param doElement - The DO Element for which to search a DOI Element. - * @param daPath - The DA Selector to create the query to find the SDI/DAI Elements. - */ -function createDaiFilter(doElement: Element, daPath: DaSelector): string { - const doName = getNameAttribute(doElement); - let filter = `:scope > DOI[name="${doName}"] > `; - daPath.path.forEach((value, index) => { - if (index < daPath.path.length - 1) { - filter = `${filter} SDI[name="${value}"] > `; - } else { - filter = `${filter} DAI[name="${value}"]`; - } - }); - return filter; -} - -/** - * Indicates if the combination cdc/ti should handle/process the attribute "unitMultiplier" of the Address Element. - * - * @param cdc - The Common Data Class. - * @param ti - The TI Value. - * @returns true, if the combination should handle/process the attribute "unitMultiplier". - */ -export function hasUnitMultiplierField(cdc: string, ti: string): boolean { - return ( - (cdc === 'MV' && ['35', '36'].includes(ti)) || - (cdc === 'INS' && ti === '35') - ); -} - -/** - * Indicates if the combination cdc/ti should handle/process the attributes "scaleMultiplier" and "scaleOffset" of - * the Address Element. - * - * @param cdc - The Common Data Class. - * @param ti - The TI Value. - * @returns true, if the combination should handle/process the attributes "scaleMultiplier" and "scaleOffset". - */ -export function hasScaleFields(cdc: string, ti: string): boolean { - return cdc === 'MV' && ['35', '36'].includes(ti); -} diff --git a/packages/plugins/src/editors/protocol104/foundation/foundation.ts b/packages/plugins/src/editors/protocol104/foundation/foundation.ts deleted file mode 100644 index 38be5a60f8..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/foundation.ts +++ /dev/null @@ -1,519 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; - -import { get } from 'lit-translate'; -import { - getInstanceAttribute, - getNameAttribute, -} from '@openscd/open-scd/src/foundation.js'; -import { typeMaxLength } from '../../../wizards/foundation/p-types.js'; -import { typeDescriptiveNameKeys, typePattern } from './p-types.js'; - -/** - * Retrieve the full path as wanted for the IED Container in the 104 Plugin, meaning we go higher in the - * hierarchy until the parent found is the IED, this element is excluded, because the containers are group per - * IED. - * From all parent between the DAI and IED the name or likely attributes are used to define a unique name. - * - * @param element - The DAI Element for which the full path needs to be defined. - * @param topLevelTagName - Name of the Tag to stop at when travelling through the parents (excluding). - * @returns The full path shown to the user for a DAI Element. - */ -export function getFullPath(element: Element, topLevelTagName: string): string { - let currentElement: Element | null = element; - const paths: string[] = []; - - do { - let value: string | undefined; - switch (currentElement.tagName) { - case 'LN': - case 'LN0': { - const prefix = currentElement.getAttribute('prefix'); - const inst = getInstanceAttribute(currentElement); - value = `${prefix ? prefix + '-' : ''}${currentElement.getAttribute( - 'lnClass' - )}${inst ? '-' + inst : ''}`; - break; - } - case 'LDevice': { - value = - getNameAttribute(currentElement) ?? - getInstanceAttribute(currentElement); - break; - } - default: { - // Just add the name to the list - value = getNameAttribute(currentElement); - } - } - if (value) { - paths.unshift(value); - } - currentElement = currentElement.parentElement; - } while (currentElement && currentElement.tagName != topLevelTagName); - - return paths.join(' / '); -} - -/** - * Retrieve the CDC Value that belongs to a DAI Element, meaning, using the DOI/LN Elements to - * search for a DO Element, which is again used to find the DO/DOType Element. The DOType Element - * finally holds the attribute 'cdc'. - * - * @param doiElement - The DOI Element to start the search for the CDC Value. - * @returns The CDC Value from the DOType Element. - */ -export function getCdcValueFromDOIElement(doiElement: Element): string | null { - const lnElement = doiElement.closest('LN0, LN'); - if (lnElement) { - const lnType = lnElement.getAttribute('lnType'); - const doName = doiElement.getAttribute('name'); - - const doElement = doiElement.ownerDocument.querySelector( - `:root > DataTypeTemplates > LNodeType[id="${lnType}"] > DO[name="${doName}"]` - ); - if (doElement) { - return getCdcValueFromDOElement(doElement); - } - } - return null; -} - -export function getCdcValueFromDOElement(doElement: Element): string | null { - const doType = getTypeAttribute(doElement); - const doTypeElement = doElement.ownerDocument.querySelector( - `:root > DataTypeTemplates > DOType[id="${doType}"]` - ); - return doTypeElement ? doTypeElement.getAttribute('cdc') : null; -} - -/** - * All available Address attributes that can be displayed. - */ -const addressAttributes = [ - 'casdu', - 'ioa', - 'ti', - 'expectedValue', - 'unitMultiplier', - 'scaleMultiplier', - 'scaleOffset', - 'inverted', - 'check', -]; - -/** - * Create a string to display all information about a 104 Address element. - * A list of attributes is used to determine what can be displayed if available. - * - * @param daiElement - The DAI Element used if the attribute 'expectedValue' exists to retrieve the Enum Value. - * @param address - The Address element from which to retrieve all attribute values. - * @returns A string to display with all attribute values. - */ -export function get104DetailsLine( - daiElement: Element, - address: Element -): string { - return addressAttributes - .filter(attrName => address.hasAttribute(attrName)) - .map(attrName => { - const value = address.getAttribute(attrName)!; - if (attrName === 'expectedValue') { - const enumValue = getEnumVal(daiElement, value); - return `${attrName}: ${value}${enumValue ? ` (${enumValue})` : ``}`; - } else { - return `${attrName}: ${value}`; - } - }) - .join(', '); -} - -/** - * Extract the 'type' attribute from the given XML element. - * @param element - The element to extract instance from. - * @returns the value, or undefined if there is no instance. - */ -export function getTypeAttribute(element: Element): string | undefined { - const type = element.getAttribute('type'); - return type ? type : undefined; -} - -/** - * Search for a DAI Element below the passed DOI Element. - * - * @param doElement - The DO Element to search on. - * @param name - The name of the DA Element to search for. - * @returns The found DA Element or null, if not found. - */ -export function getDaElement(doElement: Element, name: string): Element | null { - const doType = getTypeAttribute(doElement); - if (doType) { - return doElement.ownerDocument.querySelector( - `:root > DataTypeTemplates > DOType[id="${doType}"] > DA[name="${name}"]` - ); - } - return null; -} - -/** - * Search for the Value of a DAI Element below the passed DOI Element. - * - * @param doElement - The DO Element to search on. - * @param name - The name of the DA Element to search for. - * @returns The value (Val) of the found DA Element or null, if not found. - */ -export function getDaValue(doElement: Element, name: string): string | null { - const daElement = getDaElement(doElement, name); - if (daElement) { - return daElement.querySelector(':scope > Val')?.textContent ?? null; - } - return null; -} - -/** - * Search for a DAI Element below the passed DOI Element. - * - * @param doiElement - The DOI Element to search on. - * @param name - The name of the DAI Element to search for. - * @returns The found DAI Element or null, if not found. - */ -export function getDaiElement( - doiElement: Element, - name: string -): Element | null { - return doiElement.querySelector(`:scope > DAI[name="${name}"]`); -} - -/** - * Search for the Value of a DAI Element below the passed DOI Element. - * - * @param doiElement - The DOI Element to search on. - * @param name - The name of the DAI Element to search for. - * @returns The value (Val) of the found DAI Element or null, if not found. - */ -export function getDaiValue(doiElement: Element, name: string): string | null { - const daiElement = getDaiElement(doiElement, name); - if (daiElement) { - return daiElement.querySelector(':scope > Val')?.textContent ?? null; - } - return null; -} - -export function getDoiElement( - lnElement: Element, - doName: string -): Element | null { - return lnElement.querySelector(`:scope > DOI[name="${doName}"]`); -} - -export function getDoElement( - lnElement: Element, - doName: string -): Element | null { - const lnType = lnElement.getAttribute('lnType'); - if (lnType) { - return lnElement.ownerDocument.querySelector( - `:root > DataTypeTemplates > LNodeType[id="${lnType}"] > DO[name="${doName}"]` - ); - } - return null; -} - -export function getDoElements(lnElement: Element): Element[] { - const lnType = lnElement.getAttribute('lnType'); - if (lnType) { - return Array.from( - lnElement.ownerDocument.querySelectorAll( - `:root > DataTypeTemplates > LNodeType[id="${lnType}"] > DO` - ) - ); - } - return []; -} - -/** - * Search for the DAI Element 'ctlModel', this one indicates if control Addresses need to be created. - * - * @param lnElement - The LN Element. - * @param doElement - The DO Element. - * @returns The value of the CtlModel. - */ -export function getCtlModel( - lnElement: Element, - doElement: Element -): string | null { - const doName = getNameAttribute(doElement); - if (doName) { - const doiElement = getDoiElement(lnElement, doName); - if (doiElement) { - return getDaiValue(doiElement, 'ctlModel'); - } else { - return getDaValue(doElement, 'ctlModel'); - } - } - return null; -} - -/** - * Create a Array of Elements from the DOI Element to the passed daiElement. - * This will contain of course the DOI Element, followed by zero or more SDI Elements - * and finally the DAI Element with which we started. - * - * @param daiElement - The DAI Element to start walking to the LN(0) Element through parents. - */ -function buildInstanceChain(daiElement: Element): Element[] { - const instanceElementChain: Element[] = [daiElement]; - let child = daiElement; - if (child.parentElement) { - // While the parent element exists and the parent that was processed isn't the LN(0) Element continue. - do { - child = child.parentElement; - instanceElementChain.unshift(child); - } while (child.tagName !== 'DOI' && child.parentElement); - } - return instanceElementChain; -} - -/** - * Use the initialed elements (DOI/SDI/DAI) to make the same chain containing the template elements like - * DO/SDO/DA/BDA. This way all needed configuration values can be retrieved from the templates. - * - * @param doc - The document which will be used to search different template elements. - * @param instanceChain - The chain created from the LN(0) to the DAI in the IED. - */ -function buildTemplateChainFromInstanceElements( - doc: Document, - instanceChain: Element[] -): Element[] { - const templateChain: Element[] = []; - let typeElement: Element | null; - instanceChain.forEach(element => { - if (element.tagName === 'DOI') { - // The LN Element will only be used as starting point to find the LNodeType. - const lnElement = element.closest('LN, LN0')!; - const typeId = lnElement.getAttribute('lnType') ?? ''; - typeElement = doc.querySelector( - `:root > DataTypeTemplates > LNodeType[id="${typeId}"]` - ); - - if (typeElement) { - // Next search for the DO Element below the LNodeType Element. - const name = element.getAttribute('name'); - const doElement = typeElement.querySelector( - `:scope > DO[name="${name}"]` - ); - if (doElement) { - templateChain.push(doElement); - - // For the next element search the DOType that is linked to the DO Element. - const typeId = getTypeAttribute(doElement) ?? ''; - typeElement = doc.querySelector( - `:root > DataTypeTemplates > DOType[id="${typeId}"]` - ); - } else { - typeElement = null; - } - } - } else if (['SDI', 'DAI'].includes(element.tagName)) { - if (typeElement) { - // Search for the DA Element below the DOType or DAType from the previous Element - const name = element.getAttribute('name'); - const daElement = typeElement?.querySelector( - `:scope > DA[name="${name}"], :scope > BDA[name="${name}"]` - ); - if (daElement) { - templateChain.push(daElement); - - if (daElement.getAttribute('bType') === 'Struct') { - // Only if the bType is a struct we need to search for the DAType for the next element. - const typeId = getTypeAttribute(element) ?? ''; - typeElement = doc.querySelector( - `:root > DataTypeTemplates > DAType[id="${typeId}"]` - ); - } else { - typeElement = null; - } - } else { - typeElement = null; - } - } - } - }); - return templateChain; -} - -/** - * Retrieve the DA or BDA Element that's linked to the DAI Element passed. - * - * @param daiElement - The DAI Element for which to search the linked DA Element. - */ -export function getDaElementByDaiElement( - daiElement: Element -): Element | undefined { - // First step is to create the list of instance elements - const instanceChain = buildInstanceChain(daiElement); - // Next step is to build the Template Chain from the instance elements - const templateChain = buildTemplateChainFromInstanceElements( - daiElement.ownerDocument, - instanceChain - ); - if (templateChain.length > 0) { - // The needed DA Element is the last Element from the Chain. - const daElement = templateChain.pop(); - if (['DA', 'BDA'].includes(daElement!.tagName)) { - return daElement; - } - } - return undefined; -} - -/** - * Check if the DA Element is of the bType 'Enum'. - * - * @param daElement - The DA Element for which to check. - */ -function isEnumType(daElement: Element | undefined) { - return daElement?.getAttribute('bType') === 'Enum' ?? false; -} - -/** - * Check if the DA Element that's linked to the DAI Element is of the bType 'Enum'. - * - * @param daiElement - The DAI Element for which to check. - */ -export function isEnumDataAttribute(daiElement: Element): boolean { - const daElement = getDaElementByDaiElement(daiElement); - return isEnumType(daElement); -} - -/** - * Retrieve the value of the Enum with passed 'ord' configured with the passed DAI Element. - * - * @param daiElement - The DAI Element that is configured as Enum Type. - * @param ord - The value of the attribute 'ord' to search the value of. - */ -export function getEnumVal(daiElement: Element, ord: string): string | null { - const daElement = getDaElementByDaiElement(daiElement); - if (isEnumType(daElement)) { - const enumType = getTypeAttribute(daElement!); - const enumVal = daiElement.ownerDocument.querySelector( - `:root > DataTypeTemplates > EnumType[id="${enumType}"] > EnumVal[ord="${ord}"]` - ); - if (enumVal) { - return enumVal.textContent; - } - } - return null; -} - -/** - * Retrieve all the 'ord' value the EnumType has configured with his values. - * - * @param daiElement - The DAI Element that is configured as Enum Type. - */ -export function getEnumOrds(daiElement: Element): string[] { - const ords: string[] = []; - const daElement = getDaElementByDaiElement(daiElement); - if (isEnumType(daElement)) { - const enumType = getTypeAttribute(daElement!); - const enumVals = daiElement.ownerDocument.querySelectorAll( - `:root > DataTypeTemplates > EnumType[id="${enumType}"] > EnumVal` - ); - Array.from(enumVals) - .filter(valElement => valElement.getAttribute('ord')) - .map(valElement => ords.push(valElement.getAttribute('ord')!)); - } - return ords; -} - -/** - * Search for the Element passed from the Cloned LN Structure in the original LN Structure. - * If that element exists in the original LN Structure it will be returned. - * If the cloned Element is a new Element 'null' will be returned. - * - * @param lnElement - The original LN Element with the existing Elements. - * @param clonedElement - The Element to search for in the existing structure using its key. - * @returns The original element found or null if it didn't exist before. - */ -export function findElementInOriginalLNStructure( - lnElement: Element, - clonedElement: Element -): Element | null { - if (['LN0', 'LN'].includes(clonedElement.tagName)) { - return lnElement; - } - - // First create a list of elements from the Cloned Element to the Cloned LN Element. - const clonedElements: Element[] = []; - let currentElement: Element | null | undefined = clonedElement; - while (currentElement && !['LN0', 'LN'].includes(currentElement.tagName)) { - clonedElements.unshift(currentElement!); - currentElement = currentElement?.parentElement; - } - - // Walk through the list of Cloned Elements and walk the original LN Structure. - let parentElement: Element | null = lnElement; - while (parentElement != null && clonedElements.length > 0) { - // Get the first Cloned Element from the list and search the element on the original structure - const childElement = clonedElements.shift(); - if (childElement) { - // Below the LN there are only DOI/SDI/DAI Elements we need to search for. - // The parent can be an LN, DOI or SDI Element. - const name = getNameAttribute(childElement); - parentElement = parentElement.querySelector( - `:scope > DOI[name="${name}"], :scope > SDI[name="${name}"], :scope > DAI[name="${name}"]` - ); - } else { - parentElement = null; - } - } - return parentElement; -} - -/** - * Create a wizard-textfield element for the wizards within the Network part of the 104 plugin. - * @param pType - The type of P a Text Field has to be created for. - * @returns - A Text Field created for a specific type for the Create wizard. - */ -export function createNetworkTextField( - pType: string, - maybeValue?: string -): TemplateResult { - return html``; -} - -/** - * Enumeration stating the active view of the 104 plugin. - */ -export enum View { - VALUES, - NETWORK, -} - -export const VIEW_EVENT_NAME = 'view-change-104-plugin'; - -// Objects needed to register and fire the change of a view within the Communication 104 Plugin -export interface ViewDetail { - view: View; -} -export type ViewEvent = CustomEvent; -export function newViewEvent(view: View): ViewEvent { - return new CustomEvent(VIEW_EVENT_NAME, { - bubbles: true, - composed: true, - detail: { view }, - }); -} - -declare global { - interface ElementEventMap { - [VIEW_EVENT_NAME]: ViewEvent; - } -} diff --git a/packages/plugins/src/editors/protocol104/foundation/p-types.ts b/packages/plugins/src/editors/protocol104/foundation/p-types.ts deleted file mode 100644 index 6537afd84c..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/p-types.ts +++ /dev/null @@ -1,57 +0,0 @@ -export const pTypes104: string[] = [ - 'IP', - 'IP-SUBNET', - 'W-FACTOR', - 'K-FACTOR', - 'TIMEOUT-0', - 'TIMEOUT-1', - 'TIMEOUT-2', - 'TIMEOUT-3', -]; - -export const pTypesRedundancyGroup104: string[] = [ - 'W-FACTOR', - 'K-FACTOR', - 'TIMEOUT-0', - 'TIMEOUT-1', - 'TIMEOUT-2', - 'TIMEOUT-3', -]; - -export const pTypesLogicLink104: string[] = ['IP', 'IP-SUBNET']; - -const typeBase = { - IP: '([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])[.]([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])[.]([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])[.]([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])', - factor: - '[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-3][0-2][0-7][0-6][0-7]', - timeout: '[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]', -}; - -/** Patterns from IEC 61850-80-1 for all `P` elements */ -export const typePattern: Partial> = { - IP: typeBase.IP, - 'IP-SUBNET': typeBase.IP, - 'W-FACTOR': typeBase.factor, - 'K-FACTOR': typeBase.factor, - 'TIMEOUT-0': typeBase.timeout, - 'TIMEOUT-1': typeBase.timeout, - 'TIMEOUT-2': typeBase.timeout, - 'TIMEOUT-3': typeBase.timeout, -}; - -export const stationTypeOptions: string[] = [ - 'controlling-station', - 'controlled-station', -]; - -export const typeDescriptiveNameKeys: Record = { - StationType: 'protocol104.network.connectedAp.wizard.stationTypeHelper', - IP: 'protocol104.network.connectedAp.wizard.ipHelper', - 'IP-SUBNET': 'protocol104.network.connectedAp.wizard.ipSubnetHelper', - 'W-FACTOR': 'protocol104.network.connectedAp.wizard.wFactorHelper', - 'K-FACTOR': 'protocol104.network.connectedAp.wizard.kFactorHelper', - 'TIMEOUT-0': 'protocol104.network.connectedAp.wizard.timeout0Helper', - 'TIMEOUT-1': 'protocol104.network.connectedAp.wizard.timeout1Helper', - 'TIMEOUT-2': 'protocol104.network.connectedAp.wizard.timeout2Helper', - 'TIMEOUT-3': 'protocol104.network.connectedAp.wizard.timeout3Helper', -}; diff --git a/packages/plugins/src/editors/protocol104/foundation/private.ts b/packages/plugins/src/editors/protocol104/foundation/private.ts deleted file mode 100644 index 5a34cc7dbb..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/private.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { SCL_NAMESPACE } from '@openscd/open-scd/src/schemas.js'; - -export const PROTOCOL_104_PRIVATE = 'IEC_60870_5_104'; -export const PROTOCOL_104_NS = - 'http://www.iec.ch/61850-80-1/2007/IEC_60870-5-104'; -export const PROTOCOL_104_PREFIX = 'IEC_60870_5_104'; - -/** - * Will add the namespace of the 104 Protocol to the Root Element of the Document (SCL) as prefix to - * be used with all 104 elements (Address). - * - * @param document - The Owner Document used to registered the namespace. - */ -export function addPrefixAndNamespaceToDocument(document: Document): void { - const rootElement = document.firstElementChild!; - if (!rootElement.hasAttribute('xmlns:' + PROTOCOL_104_PREFIX)) { - rootElement.setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - 'xmlns:' + PROTOCOL_104_PREFIX, - PROTOCOL_104_NS - ); - } -} - -/** - * Get the SCL Private Element with the type set to the 104 Protocol. - * - * @param daiElement - The DAI Element to search for the 104 Private Element. - * @returns The found Private Element or null if not there. - */ -export function getPrivateElement(daiElement: Element): Element | null { - return daiElement.querySelector(`Private[type="${PROTOCOL_104_PRIVATE}"]`); -} - -/** - * Create an SCL Private Element with the type set to the 104 Protocol. - * - * @param document - The Owner Document used to create the new Private Element with. - * @returns The created Private Element, not yet added to the DAI Element. - */ -export function createPrivateElement(document: Document): Element { - const privateElement = document.createElementNS(SCL_NAMESPACE, 'Private'); - privateElement.setAttribute('type', PROTOCOL_104_PRIVATE); - return privateElement; -} - -/** - * Create a 104 Address element which can be added to the Private element. - * The attribute 'ti' will also be set to value passed. - * - * @param document - The Owner Document used to create the new Address Element with. - * @param ti - The value for the attribute 'ti'. - */ -export function createPrivateAddress(document: Document, ti: string): Element { - const addressElement = document.createElementNS(PROTOCOL_104_NS, 'Address'); - addressElement.setAttribute('ti', ti); - return addressElement; -} diff --git a/packages/plugins/src/editors/protocol104/foundation/signalNames.ts b/packages/plugins/src/editors/protocol104/foundation/signalNames.ts deleted file mode 100644 index 196af983b6..0000000000 --- a/packages/plugins/src/editors/protocol104/foundation/signalNames.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { get } from 'lit-translate'; - -export function getSignalName(tiNumber: string): string { - switch (tiNumber) { - case '1': - return get('protocol104.values.signalNames.tiNumber1'); - case '3': - return get('protocol104.values.signalNames.tiNumber3'); - case '5': - return get('protocol104.values.signalNames.tiNumber5'); - case '7': - return get('protocol104.values.signalNames.tiNumber7'); - case '9': - return get('protocol104.values.signalNames.tiNumber9'); - case '11': - return get('protocol104.values.signalNames.tiNumber11'); - case '13': - return get('protocol104.values.signalNames.tiNumber13'); - case '15': - return get('protocol104.values.signalNames.tiNumber15'); - case '20': - return get('protocol104.values.signalNames.tiNumber20'); - case '21': - return get('protocol104.values.signalNames.tiNumber21'); - case '30': - return get('protocol104.values.signalNames.tiNumber30'); - case '31': - return get('protocol104.values.signalNames.tiNumber31'); - case '32': - return get('protocol104.values.signalNames.tiNumber32'); - case '33': - return get('protocol104.values.signalNames.tiNumber33'); - case '34': - return get('protocol104.values.signalNames.tiNumber34'); - case '35': - return get('protocol104.values.signalNames.tiNumber35'); - case '36': - return get('protocol104.values.signalNames.tiNumber36'); - case '37': - return get('protocol104.values.signalNames.tiNumber37'); - case '38': - return get('protocol104.values.signalNames.tiNumber38'); - case '39': - return get('protocol104.values.signalNames.tiNumber39'); - case '40': - return get('protocol104.values.signalNames.tiNumber40'); - case '45': - return get('protocol104.values.signalNames.tiNumber45'); - case '46': - return get('protocol104.values.signalNames.tiNumber46'); - case '47': - return get('protocol104.values.signalNames.tiNumber47'); - case '48': - return get('protocol104.values.signalNames.tiNumber48'); - case '49': - return get('protocol104.values.signalNames.tiNumber49'); - case '50': - return get('protocol104.values.signalNames.tiNumber50'); - case '51': - return get('protocol104.values.signalNames.tiNumber51'); - case '58': - return get('protocol104.values.signalNames.tiNumber58'); - case '59': - return get('protocol104.values.signalNames.tiNumber59'); - case '60': - return get('protocol104.values.signalNames.tiNumber60'); - case '61': - return get('protocol104.values.signalNames.tiNumber61'); - case '62': - return get('protocol104.values.signalNames.tiNumber62'); - case '63': - return get('protocol104.values.signalNames.tiNumber63'); - case '64': - return get('protocol104.values.signalNames.tiNumber64'); - default: - return get('protocol104.values.signalNames.default'); - } -} diff --git a/packages/plugins/src/editors/protocol104/ied-container.ts b/packages/plugins/src/editors/protocol104/ied-container.ts deleted file mode 100644 index 3ef6d56e6d..0000000000 --- a/packages/plugins/src/editors/protocol104/ied-container.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { - css, - customElement, - html, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; -import { nothing } from 'lit-html'; - -import { IconButtonToggle } from '@material/mwc-icon-button-toggle'; - -import '@material/mwc-icon'; -import '@material/mwc-icon-button-toggle'; - -import { - getDescriptionAttribute, - getNameAttribute, -} from '@openscd/open-scd/src/foundation.js'; - -import '@openscd/open-scd/src/action-pane.js'; - -import { getFullPath } from './foundation/foundation.js'; - -import './doi-container.js'; -import { PROTOCOL_104_PRIVATE } from './foundation/private.js'; -import { Base104Container } from './base-container.js'; - -/** - * Container showing all the DOI Elements, related to the 104 Protocol, of the passed IED Element in a container. - */ -@customElement('ied-104-container') -export class Ied104Container extends Base104Container { - @property() - element!: Element; - - @query('#toggleButton') - toggleButton!: IconButtonToggle | undefined; - - @property() - get doiElements(): Element[] { - return Array.from(this.element.querySelectorAll(`DOI`)) - .filter( - doiElement => - doiElement.querySelector( - `DAI > Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ) !== null - ) - .sort((doi1, doi2) => - getFullPath(doi1, 'IED').localeCompare(getFullPath(doi2, 'IED')) - ); - } - - protected firstUpdated(): void { - this.requestUpdate(); - } - - @property() - get header(): TemplateResult { - const name = getNameAttribute(this.element); - const desc = getDescriptionAttribute(this.element); - - return html`${name}${desc ? html` — ${desc}` : nothing}`; - } - - private renderDoiList(): TemplateResult { - const dois = this.doiElements; - return html`${dois.map(doiElement => { - return html` - - - `; - })}`; - } - - render(): TemplateResult { - return html` - - developer_board - - this.requestUpdate()} - > - - - ${this.toggleButton?.on ? html`${this.renderDoiList()}` : nothing} - - `; - } - - static styles = css` - abbr { - text-decoration: none; - border-bottom: none; - } - `; -} diff --git a/packages/plugins/src/editors/protocol104/network-container.ts b/packages/plugins/src/editors/protocol104/network-container.ts deleted file mode 100644 index 01a8b462e6..0000000000 --- a/packages/plugins/src/editors/protocol104/network-container.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { get } from 'lit-translate'; -import { css, customElement, html, TemplateResult } from 'lit-element'; - -import './subnetwork-container.js'; -import { - compareNames, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; - -import { createElement } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { createSubNetworkWizard } from './wizards/subnetwork.js'; -import { Base104Container } from './base-container.js'; -import { getTypeAttribute } from './foundation/foundation.js'; - -@customElement('network-104-container') -export class Network104Container extends Base104Container { - private getSubNetworkElements(): Element[] { - return Array.from( - this.doc.querySelectorAll('Communication > SubNetwork') ?? [] - ) - .filter(network => getTypeAttribute(network) === '104') - .sort((a, b) => compareNames(a, b)); - } - - /** Opens a [[`WizardDialog`]] for creating a new `SubNetwork` element. */ - private openCreateSubNetworkWizard(): void { - const parent = this.doc.querySelector(':root > Communication'); - if (!parent) { - this.dispatchEvent( - newActionEvent({ - new: { - parent: this.doc.documentElement, - element: createElement(this.doc, 'Communication', {}), - }, - }) - ); - } - this.dispatchEvent(newWizardEvent(createSubNetworkWizard(parent!))); - } - - render(): TemplateResult { - return html` this.openCreateSubNetworkWizard()} - > -
- ${this.getSubNetworkElements().map( - subnetwork => - html`` - )} -
`; - } - - static styles = css` - :host { - width: 100vw; - } - - mwc-fab { - position: fixed; - bottom: 32px; - right: 32px; - } - - subnetwork-104-container { - margin: 8px 12px 16px; - } - `; -} diff --git a/packages/plugins/src/editors/protocol104/subnetwork-container.ts b/packages/plugins/src/editors/protocol104/subnetwork-container.ts deleted file mode 100644 index dc78c92bad..0000000000 --- a/packages/plugins/src/editors/protocol104/subnetwork-container.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { - css, - customElement, - html, - property, - TemplateResult, -} from 'lit-element'; - -import '@material/mwc-icon-button'; - -import './connectedap-editor.js'; - -import { - compareNames, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { get } from 'lit-translate'; -import { createConnectedApWizard } from './wizards/connectedap.js'; -import { Base104Container } from './base-container.js'; -import { getTypeAttribute } from './foundation/foundation.js'; - -/** [[`104`]] subeditor for a `SubNetwork` element. */ -@customElement('subnetwork-104-container') -export class SubNetwork104Container extends Base104Container { - /** SCL element SubNetwork */ - @property({ attribute: false }) - element!: Element; - - get bitrate(): string | null { - const bitRate = this.element.querySelector('BitRate'); - if (bitRate === null) return null; - const bitRateValue = bitRate.textContent ?? ''; - const m = bitRate.getAttribute('multiplier'); - const unit = m === null ? 'b/s' : ' ' + m + 'b/s'; - return bitRateValue ? bitRateValue + unit : null; - } - - private openConnectedAPwizard(): void { - this.dispatchEvent(newWizardEvent(createConnectedApWizard(this.element))); - } - - private renderIedContainer(): TemplateResult[] { - return Array.from(this.element.querySelectorAll(':scope > ConnectedAP')) - .map(connAP => connAP.getAttribute('iedName')!) - .filter((v, i, a) => a.indexOf(v) === i) - .sort(compareNames) - .map( - iedName => html` - ${Array.from( - this.element.parentElement?.querySelectorAll( - `:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]` - ) ?? [] - ).map( - connectedAP => - html`` - )} - ` - ); - } - - private subNetworkSpecs(): string { - const type = getTypeAttribute(this.element) ?? null; - - if (!type && !this.bitrate) return ''; - - return `(${type}${type && this.bitrate ? ` — ${this.bitrate}` : ``})`; - } - - private header(): string { - const desc = this.element.getAttribute('desc') ?? null; - const name = this.element.getAttribute('name') ?? undefined; - - return ` ${name} ${desc === null ? '' : `— ${desc}`} - ${this.subNetworkSpecs()}`; - } - - render(): TemplateResult { - return html` - - - -
${this.renderIedContainer()}
-
`; - } - - static styles = css` - #iedContainer { - display: grid; - box-sizing: border-box; - gap: 12px; - padding: 8px 12px 16px; - grid-template-columns: repeat(auto-fit, minmax(150px, auto)); - } - - #iedSection:not(:focus):not(:focus-within) .disabled { - display: none; - } - - #iedSection .disabled { - pointer-events: none; - opacity: 0.5; - } - `; -} diff --git a/packages/plugins/src/editors/protocol104/values-container.ts b/packages/plugins/src/editors/protocol104/values-container.ts deleted file mode 100644 index 06eeb7180c..0000000000 --- a/packages/plugins/src/editors/protocol104/values-container.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { - css, - customElement, - html, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import { - compareNames, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; - -import './ied-container.js'; - -import { selectDoWizard } from './wizards/selectDo.js'; -import { PROTOCOL_104_PRIVATE } from './foundation/private.js'; -import { Base104Container } from './base-container.js'; - -/** - * Container that will render an 'ied-104-container' for every IED which contains DAI Elements related to the - * 104 Protocol. - */ -@customElement('values-104-container') -export class Values104Container extends Base104Container { - @property() - get iedElements(): Element[] { - return Array.from(this.doc.querySelectorAll('IED')) - .filter( - ied => - ied.querySelectorAll( - `DAI > Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ).length > 0 - ) - .sort((a, b) => compareNames(a, b)); - } - - /** Opens a [[`WizardDialog`]] for creating a new `Substation` element. */ - private openCreateAddressWizard(): void { - this.dispatchEvent(newWizardEvent(selectDoWizard(this.doc))); - } - - private renderAddButton(): TemplateResult { - return html`

- this.openCreateAddressWizard()} - > - -

`; - } - - render(): TemplateResult { - const ieds = this.iedElements; - if (ieds.length > 0) { - return html` - ${ieds.map(iedElement => { - return html``; - })} - ${this.renderAddButton()} - `; - } - return html`

- ${get('protocol104.values.missing')} -

- ${this.renderAddButton()}`; - } - - static styles = css` - mwc-fab { - position: fixed; - bottom: 32px; - right: 32px; - } - - h1 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - } - `; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/address.ts b/packages/plugins/src/editors/protocol104/wizards/address.ts deleted file mode 100644 index b25e5ea809..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/address.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; -import { live } from 'lit-html/directives/live'; - -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; -import '@material/mwc-textarea'; - -import { - getNameAttribute, - getValue, - patterns, - Wizard, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement } from '@openscd/xml'; - -import { EditorAction } from '@openscd/core/foundation/deprecated/editor.js'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import '@openscd/open-scd/src/wizard-select.js'; - -import { - getCdcValueFromDOIElement, - getEnumVal, - getFullPath, -} from '../foundation/foundation.js'; -import { hasScaleFields, hasUnitMultiplierField } from '../foundation/cdc.js'; -import { getSignalName } from '../foundation/signalNames.js'; - -const allowedMultipliers = [ - 'm', - 'k', - 'M', - 'mu', - 'y', - 'z', - 'a', - 'f', - 'p', - 'n', - 'c', - 'd', - 'da', - 'h', - 'G', - 'T', - 'P', - 'E', - 'Z', - 'Y', -]; - -export function updateAddressValue( - doiElement: Element, - daiElement: Element, - addressElement: Element -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const foundCdc = getCdcValueFromDOIElement(doiElement) ?? ''; - const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; - const ti = addressElement.getAttribute('ti') ?? ''; - - const casdu = getValue(inputs.find(i => i.label === 'casdu')!)!; - const ioa = getValue(inputs.find(i => i.label === 'ioa')!); - const unitMultiplier = hasUnitMultiplierField(cdc, ti) - ? getValue(inputs.find(i => i.label === 'unitMultiplier')!) - : null; - const scaleMultiplier = hasScaleFields(cdc, ti) - ? getValue(inputs.find(i => i.label === 'scaleMultiplier')!) - : null; - const scaleOffset = hasScaleFields(cdc, ti) - ? getValue(inputs.find(i => i.label === 'scaleOffset')!) - : null; - - if ( - casdu === addressElement.getAttribute('casdu') && - ioa === addressElement.getAttribute('ioa') && - unitMultiplier === addressElement.getAttribute('unitMultiplier') && - scaleMultiplier === addressElement.getAttribute('scaleMultiplier') && - scaleOffset === addressElement.getAttribute('scaleOffset') - ) { - return []; - } - - const newElement = cloneElement(addressElement, { - casdu, - ioa, - unitMultiplier, - scaleMultiplier, - scaleOffset, - }); - - return [ - { old: { element: addressElement! }, new: { element: newElement } }, - ]; - }; -} - -export function editAddressWizard( - iedElement: Element, - doiElement: Element, - daiElement: Element, - addressElement: Element -): Wizard { - function renderAddressWizard(): TemplateResult[] { - const foundCdc = getCdcValueFromDOIElement(doiElement) ?? ''; - const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL'; - const cdc = reqCmvMapping ? 'CMV' : foundCdc; - const ti = addressElement.getAttribute('ti') ?? ''; - - let casdu = addressElement.getAttribute('casdu') ?? ''; - - function validateIOA( - this: WizardInputElement, - value: string - ): Partial { - const existingAddress = iedElement.querySelector( - `Address[casdu="${casdu}"][ioa="${value}"]` - ); - if (existingAddress) { - this.validationMessage = get('protocol104.wizard.error.ioaConflict'); - return { - valid: false, - customError: true, - }; - } - return {}; - } - - // Add the basic fields to the list. - const fields: TemplateResult[] = [ - html` - `, - html` - `, - html` - `, - html` - `, - html` - `, - html` - `, - html` - `, - ]; - - if (hasUnitMultiplierField(cdc, ti)) { - fields.push(html` - ${allowedMultipliers.map( - multiplier => - html` - ${multiplier} - ` - )} - `); - } - - if (hasScaleFields(cdc, ti)) { - fields.push(html` - `); - - fields.push(html` - `); - } - - const expectedValue = addressElement.getAttribute('expectedValue'); - if (expectedValue) { - fields.push(html` - `); - fields.push(html` - `); - } - - if (addressElement.hasAttribute('inverted')) { - fields.push(html` - `); - } - - if (addressElement.hasAttribute('check')) { - fields.push(html` - `); - } - - return fields; - } - - return [ - { - title: get('protocol104.wizard.title.addressEdit'), - element: addressElement, - primary: { - icon: 'edit', - label: get('save'), - action: updateAddressValue(doiElement, daiElement, addressElement), - }, - content: renderAddressWizard(), - }, - ]; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/connectedap.ts b/packages/plugins/src/editors/protocol104/wizards/connectedap.ts deleted file mode 100644 index 03f5fb64c9..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/connectedap.ts +++ /dev/null @@ -1,406 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; -import { ifDefined } from 'lit-html/directives/if-defined'; - -import '@material/mwc-checkbox'; -import '@material/mwc-switch'; -import '@material/mwc-formfield'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-list/mwc-check-list-item'; -import '@material/mwc-icon'; - -import { Checkbox } from '@material/mwc-checkbox'; -import { List } from '@material/mwc-list'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import '@openscd/open-scd/src/filtered-list.js'; - -import { - pTypes104, - stationTypeOptions, - typeDescriptiveNameKeys, - typePattern, -} from '../foundation/p-types.js'; -import { - compareNames, - getValue, - identity, - isPublic, - newSubWizardEvent, - newWizardEvent, - Wizard, - WizardActor, - WizardInputElement, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement, createElement } from '@openscd/xml'; - -import { - ComplexAction, - EditorAction, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { getTypeAttribute } from '../foundation/foundation.js'; -import { - createRedundancyGroupWizard, - editRedundancyGroupWizard, -} from './redundancygroup.js'; - -interface AccessPointDescription { - element: Element; - connected?: boolean; -} - -/** Sorts connected `AccessPoint`s to the bottom. */ -function compareAccessPointConnection( - a: AccessPointDescription, - b: AccessPointDescription -): number { - if (a.connected !== b.connected) return b.connected ? -1 : 1; - return 0; -} - -function createConnectedApAction(parent: Element): WizardActor { - return ( - _: WizardInputElement[], - __: Element, - list?: List | null - ): EditorAction[] => { - if (!list) return []; - - const identities = (list.selected).map(item => item.value); - - const actions = identities.map(identity => { - const [iedName, apName] = identity.split('>'); - - return { - new: { - parent, - element: createElement(parent.ownerDocument, 'ConnectedAP', { - iedName, - apName, - }), - }, - }; - }); - - return actions; - }; -} - -function existConnectedAp(accesspoint: Element): boolean { - const iedName = accesspoint.closest('IED')?.getAttribute('name'); - const apName = accesspoint.getAttribute('name'); - - const connAp = accesspoint.ownerDocument.querySelector( - `ConnectedAP[iedName="${iedName}"][apName="${apName}"]` - ); - - return (connAp && isPublic(connAp)) ?? false; -} - -/** @returns single page [[`Wizard`]] for creating SCL element ConnectedAP. */ -export function createConnectedApWizard(element: Element): Wizard { - const doc = element.ownerDocument; - - const accessPoints = Array.from(doc.querySelectorAll(':root > IED')) - .sort(compareNames) - .flatMap(ied => - Array.from(ied.querySelectorAll(':root > IED > AccessPoint')) - ) - .map(accesspoint => { - return { - element: accesspoint, - connected: existConnectedAp(accesspoint), - }; - }) - .sort(compareAccessPointConnection); - - return [ - { - title: get('wizard.title.add', { tagName: 'ConnectedAP' }), - primary: { - icon: 'save', - label: get('save'), - action: createConnectedApAction(element), - }, - content: [ - html` ${accessPoints.map(accesspoint => { - const id = identity(accesspoint.element); - - return html`${id}`; - })} - `, - ], - }, - ]; -} - -function isEqualAddress(oldAddress: Element, newAddress: Element): boolean { - return Array.from(oldAddress.querySelectorAll('Address > P')).every(pType => - newAddress - .querySelector(`Address > P[type="${getTypeAttribute(pType)}"]`) - ?.isEqualNode(pType) - ); -} - -function createAddressElement( - inputs: WizardInputElement[], - parent: Element, - typeRestriction: boolean -): Element { - const element = createElement(parent.ownerDocument, 'Address', {}); - - inputs - .filter(input => getValue(input) !== null) - .forEach(validInput => { - const type = validInput.label; - const child = createElement(parent.ownerDocument, 'P', { type }); - - if (typeRestriction) - child.setAttributeNS( - 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:type', - 'tP_' + type - ); - - child.textContent = getValue(validInput); - element.appendChild(child); - }); - - return element; -} - -/** @returns single page [[`Wizard`]] to edit SCL element ConnectedAP for the 104 plugin. */ -export function editConnectedApWizard( - parent: Element, - redundancy?: boolean -): Wizard { - const redundancyGroupNumbers = getRedundancyGroupNumbers(parent); - return [ - { - title: get('protocol104.network.connectedAp.wizard.title.edit'), - element: parent, - menuActions: redundancy - ? [ - { - icon: 'playlist_add', - label: get( - 'protocol104.network.connectedAp.wizard.addRedundancyGroup' - ), - action: openRedundancyGroupWizard(parent, redundancyGroupNumbers), - }, - ] - : undefined, - primary: { - icon: 'save', - label: get('save'), - action: editConnectedApAction(parent, redundancy), - }, - content: [ - html` - { - event.target!.dispatchEvent(newWizardEvent()); - event.target!.dispatchEvent( - newSubWizardEvent(() => - editConnectedApWizard(parent, !redundancy) - ) - ); - }} - > - - - ${createTypeRestrictionCheckbox(parent)} - P[type="StationType"]` - )?.innerHTML ?? null} - required - fixedMenuPosition - helper="${get(typeDescriptiveNameKeys['StationType'])}" - > - ${stationTypeOptions.map( - option => - html`${option}` - )} - - ${redundancy - ? html`

- ${get( - 'protocol104.network.connectedAp.wizard.redundancyGroupTitle' - )} -

- { - e.target!.dispatchEvent( - newSubWizardEvent(() => - editRedundancyGroupWizard( - parent, - redundancyGroupNumbers[e.detail.index] - ) - ) - ); - }} - > - ${redundancyGroupNumbers.length != 0 - ? redundancyGroupNumbers.map( - number => - html`Redundancy Group ${number}` - ) - : html`

- ${get( - 'protocol104.network.connectedAp.wizard.noRedundancyGroupsAvailable' - )} -

`} -
` - : html`${pTypes104.map( - pType => html`${createEditTextField(parent, pType)}` - )}`} `, - ], - }, - ]; -} - -function editConnectedApAction( - parent: Element, - redundancy?: boolean -): WizardActor { - return (inputs: WizardInputElement[], wizard: Element): EditorAction[] => { - const typeRestriction: boolean = - (wizard.shadowRoot?.querySelector('#typeRestriction')) - ?.checked ?? false; - - const newAddress = createAddressElement(inputs, parent, typeRestriction); - const oldAddress = parent.querySelector('Address'); - - const complexAction: ComplexAction = { - actions: [], - title: get('connectedap.action.addaddress', { - iedName: parent.getAttribute('iedName') ?? '', - apName: parent.getAttribute('apName') ?? '', - }), - }; - // When we have a redundanct ConnectedAP, we are only interested in the StationType value. - // All redundancy group actions are done in those wizards itself. - if (redundancy) { - const stationTypeValue = getValue( - inputs.find(i => i.label === 'StationType')! - )!; - const originalElement = oldAddress?.querySelector( - 'P[type="StationType"]' - ); - - const elementClone = cloneElement(originalElement!, {}); - elementClone!.textContent = stationTypeValue; - - complexAction.actions.push({ - old: { - element: originalElement!, - }, - new: { - element: elementClone, - }, - }); - } else if (oldAddress !== null && !isEqualAddress(oldAddress, newAddress)) { - //address & child elements P are changed: cannot use replace editor action - complexAction.actions.push({ - old: { - parent, - element: oldAddress, - }, - }); - complexAction.actions.push({ - new: { - parent, - element: newAddress, - }, - }); - } else if (oldAddress === null) - complexAction.actions.push({ - new: { - parent: parent, - element: newAddress, - }, - }); - - return complexAction.actions.length ? [complexAction] : []; - }; -} - -function openRedundancyGroupWizard( - element: Element, - rGNumbers: number[] -): WizardMenuActor { - return (wizard: Element): void => { - wizard.dispatchEvent( - newSubWizardEvent(createRedundancyGroupWizard(element, rGNumbers)) - ); - }; -} - -/** - * Get all the current used Redundancy Group numbers. - * @param parent - The parent element of all the P elements. - * @returns An array with all the Redundancy Group numbers. - */ -function getRedundancyGroupNumbers(parent: Element): number[] { - const groupNumbers: number[] = []; - - parent.querySelectorAll(`Address > P[type^="RG"]`).forEach(p => { - const redundancyGroupPart = getTypeAttribute(p)?.split('-')[0]; - const number = Number(redundancyGroupPart?.substring(2)); - - if (!groupNumbers.includes(number)) groupNumbers.push(number); - }); - - return groupNumbers.sort(); -} - -/** - * Create a wizard-textfield element for the Edit wizard. - * @param parent - The parent element of the P to create. - * @param pType - The type of P a Text Field has to be created for. - * @returns - A Text Field created for a specific type for the Edit wizard. - */ -function createEditTextField(parent: Element, pType: string): TemplateResult { - return html` P[type="${pType}"]`) - ?.innerHTML ?? null} - >`; -} - -function createTypeRestrictionCheckbox(element: Element): TemplateResult { - return html` - `; -} - -function hasTypeRestriction(element: Element): boolean { - return Array.from(element.querySelectorAll('Address > P')) - .filter(p => isPublic(p)) - .some(pType => pType.getAttribute('xsi:type')); -} diff --git a/packages/plugins/src/editors/protocol104/wizards/createAddresses.ts b/packages/plugins/src/editors/protocol104/wizards/createAddresses.ts deleted file mode 100644 index e48e2907bc..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/createAddresses.ts +++ /dev/null @@ -1,434 +0,0 @@ -import { get } from 'lit-translate'; -import { html, TemplateResult } from 'lit-element'; -import { Select } from '@material/mwc-select'; -import { SelectedEvent } from '@material/mwc-list/mwc-list-foundation'; - -import { Switch } from '@material/mwc-switch'; - -import '@material/mwc-formfield'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-switch'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import '@openscd/open-scd/src/WizardDivider.js'; -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; - -import { - getNameAttribute, - getValue, - newWizardEvent, - Wizard, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - EditorAction, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - getCdcValueFromDOElement, - getCtlModel, - getFullPath, -} from '../foundation/foundation.js'; -import { - cdcProcessings, - SupportedCdcType, - TiInformation, -} from '../foundation/cdc.js'; -import { createActions, createCheckActions } from '../foundation/actions.js'; -import { getSignalName } from '../foundation/signalNames.js'; - -function getSwitchValue(wizard: Element, name: string): boolean { - const switchElement = wizard.shadowRoot?.querySelector( - `mwc-switch[id="${name}"` - ) as Switch; - return switchElement?.checked ?? false; -} - -export function createAddressesAction( - lnElement: Element, - doElement: Element, - hasControlTis: boolean -): WizardActor { - return (inputs: WizardInputElement[], wizard: Element): EditorAction[] => { - // Close previous wizard (SelectDO) to prevent it from showing after saving. - wizard.dispatchEvent(newWizardEvent()); - - const cdc = getCdcValueFromDOElement(doElement) ?? ''; - const cdcProcessing = cdcProcessings[cdc]; - const complexAction: ComplexAction = { - actions: [], - title: get('protocol104.values.addedAddress', { - name: getNameAttribute(doElement) ?? 'Unknown', - lnName: getFullPath(lnElement, 'IED'), - }), - }; - - // Create a Deep Clone of the LN Element, to keep track on which structure is initialized. - const lnClonedElement = lnElement.cloneNode(true); - - // Create all Monitor Addresses - const selectedMonitorTi = - getValue(inputs.find(i => i.label === 'monitorTi')!)?.split(' (')[0] ?? - ''; - const monitorInverted = getSwitchValue(wizard, 'monitorInverted'); - const tiInformation = cdcProcessing.monitor[selectedMonitorTi]; - if (tiInformation) { - complexAction.actions.push( - ...createActions( - lnElement, - lnClonedElement, - doElement, - wizard, - selectedMonitorTi, - monitorInverted, - tiInformation - ) - ); - } - - const monitorCheck = getSwitchValue(wizard, 'monitorCheck'); - if (monitorCheck) { - complexAction.actions.push( - ...createCheckActions( - lnElement, - lnClonedElement, - doElement, - wizard, - selectedMonitorTi, - tiInformation - ) - ); - } - - // Create all Control Addresses - if (hasControlTis) { - const ctlModel = getCtlModel(lnElement, doElement); - if (ctlModel !== null && ctlModel !== 'status-only') { - const selectedControlTi = - getValue(inputs.find(i => i.label === 'controlTi')!)?.split( - ' (' - )[0] ?? ''; - const controlInverted = getSwitchValue(wizard, 'controlInverted'); - - const tiInformation = cdcProcessing.control[selectedControlTi]; - if (tiInformation) { - complexAction.actions.push( - ...createActions( - lnElement, - lnClonedElement, - doElement, - wizard, - selectedControlTi, - controlInverted, - tiInformation - ) - ); - } - - const controlCheck = getSwitchValue(wizard, 'controlCheck'); - if (controlCheck) { - complexAction.actions.push( - ...createCheckActions( - lnElement, - lnClonedElement, - doElement, - wizard, - selectedControlTi, - tiInformation - ) - ); - } - } - } - - if (complexAction.actions.length > 0) { - return [complexAction]; - } - // There are no Address elements created for any DAI, close window. - wizard.dispatchEvent(newWizardEvent()); - return []; - }; -} - -export function disableCheckSwitch( - tiInfo: Record -): boolean { - let disableSwitch = true; - Object.values(tiInfo).forEach(tiInformation => { - if (tiInformation.checkDaPaths && tiInformation.checkCreate) { - disableSwitch = false; - } - }); - return disableSwitch; -} - -export function disableInvertedSwitch( - tiInfo: Record -): boolean { - let disableSwitch = true; - Object.values(tiInfo).forEach(tiInformation => { - if (tiInformation.inverted === true) { - disableSwitch = false; - } - }); - return disableSwitch; -} - -export function disableMonitorInvertedSwitch( - tiInfo: Record, - tiNumberInfo: string -): boolean { - let disableSwitch = true; - const tiNumber = tiNumberInfo.split(' (')[0]; - - if (!isNaN(+tiNumber)) disableSwitch = !tiInfo[tiNumber].inverted; - - return disableSwitch; -} - -export function createAddressesWizard( - lnElement: Element, - doElement: Element -): Wizard { - const foundCdc = getCdcValueFromDOElement(doElement) ?? ''; - const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL'; - const cdc = reqCmvMapping ? 'CMV' : foundCdc; - const cdcProcessing = cdcProcessings[foundCdc]; - - const monitorTis = Object.keys(cdcProcessing.monitor); - const controlTis = Object.keys(cdcProcessing.control); - - function renderCreateAddressesWizard(): TemplateResult[] { - const doName = getNameAttribute(doElement) ?? ''; - const iedElement = lnElement.closest('IED'); - const fullPath = getFullPath(lnElement, 'IED'); - - function setMonitorInvertedSwitch(e: SelectedEvent): void { - const selectedTi = (e.target).parentElement!.querySelector( - 'mwc-switch[id="monitorInverted"]' - ); - - if (!selectElement) return; - - (selectElement).disabled = disableMonitorInvertedSwitch( - cdcProcessing.monitor, - selectedTi - ); - } - - function setMonitorControlValue( - e: SelectedEvent, - isMonitor: boolean - ): void { - const selectedTi = (e.target).parentElement!.querySelector( - `wizard-select[label="${counterType}"]` - ) as WizardSelect; - - availableTis.maybeValue = isMonitor - ? selectedTi === '30' - ? '58' - : '62' - : selectedTi === '58' - ? '30' - : '35'; - } - - // Add the basic fields to the list. - const fields = [ - html` - `, - html` - `, - html` - `, - html` - `, - ]; - - if (monitorTis.length > 0) { - fields.push(html``); - let disabledSwitchByDefault = true; - if (monitorTis.length > 1) { - fields.push( - html` { - setMonitorInvertedSwitch(e); - if (cdc === 'ENC') setMonitorControlValue(e, true); - }} - > - ${monitorTis.map( - monitorTi => - html` - ${monitorTi + ' (' + getSignalName(monitorTi) + ')'} - ` - )} - ` - ); - } else { - disabledSwitchByDefault = disableMonitorInvertedSwitch( - cdcProcessing.monitor, - monitorTis[0] - ); - fields.push( - html` - ` - ); - } - fields.push( - html` - - - ` - ); - fields.push( - html` - - - ` - ); - } - - if (controlTis.length > 0) { - fields.push(html` `); - - const ctlModel = getCtlModel(lnElement, doElement); - if (ctlModel !== null) { - fields.push(html` - `); - } - - if (ctlModel !== null && ctlModel !== 'status-only') { - if (controlTis.length > 1) { - fields.push( - html` { - if (cdc === 'ENC') setMonitorControlValue(e, false); - }} - > - ${controlTis.map( - controlTi => - html` - ${controlTi + - ' (' + - getSignalName(controlTi) + - ')'} - ` - )} - ` - ); - } else { - fields.push( - html` - ` - ); - } - fields.push( - html` - - - ` - ); - fields.push( - html` - - - ` - ); - } - } - return fields; - } - - return [ - { - title: get('wizard.title.add', { tagName: 'Address' }), - primary: { - icon: 'add', - label: get('add'), - action: createAddressesAction( - lnElement, - doElement, - controlTis.length > 0 - ), - }, - content: renderCreateAddressesWizard(), - }, - ]; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/doi.ts b/packages/plugins/src/editors/protocol104/wizards/doi.ts deleted file mode 100644 index bf6fb87f1c..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/doi.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-textarea'; - -import { - getNameAttribute, - newWizardEvent, - Wizard, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; -import '@openscd/open-scd/src/wizard-textfield.js'; - -import { - getCdcValueFromDOIElement, - getCtlModel, - getDoElement, - getFullPath, -} from '../foundation/foundation.js'; -import { cdcProcessings, SupportedCdcType } from '../foundation/cdc.js'; -import { PROTOCOL_104_PRIVATE } from '../foundation/private.js'; - -function renderTiOverview(foundTis: string[], label: string): TemplateResult { - if (foundTis.length > 0) { - return html` - `; - } - return html``; -} - -export function renderDOIWizard(doiElement: Element): TemplateResult[] { - const iedElement = doiElement.closest('IED'); - const fullpath = getFullPath(doiElement, 'IED'); - const foundCdc = getCdcValueFromDOIElement(doiElement); - const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; - - // Add the basic fields to the list. - const fields: TemplateResult[] = [ - html` - `, - html` - `, - html` - `, - ]; - - const lnElement = doiElement.closest('LN0, LN'); - const doName = getNameAttribute(doiElement); - if (lnElement && doName) { - const doElement = getDoElement(lnElement, doName); - if (doElement) { - const ctlModel = getCtlModel(lnElement, doElement); - if (ctlModel !== null) { - fields.push(html` - `); - } - } - } - - let monitorTis: string[] = []; - let controlTis: string[] = []; - const cdcProcessing = cdcProcessings[cdc]; - fields.push(html` - `); - if (cdcProcessing) { - monitorTis = Object.keys(cdcProcessing.monitor); - controlTis = Object.keys(cdcProcessing.control); - } - - let foundTis = Array.from( - doiElement.querySelectorAll( - `DAI > Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ) - ) - .filter(element => element.getAttribute('ti') !== '') - .map(element => element.getAttribute('ti')!); - // Remove duplicates from the array. - foundTis = [...new Set(foundTis)]; - - const foundMonitorTis = foundTis.filter(ti => monitorTis.includes(ti)); - const foundControlTis = foundTis.filter(ti => controlTis.includes(ti)); - const otherTis = foundTis - .filter(ti => !foundMonitorTis.includes(ti)) - .filter(ti => !foundControlTis.includes(ti)); - - fields.push(renderTiOverview(monitorTis, 'Available Monitor TIs')); - fields.push(renderTiOverview(foundMonitorTis, 'Found Monitor TIs')); - fields.push(renderTiOverview(controlTis, 'Available Control TIs')); - fields.push(renderTiOverview(foundControlTis, 'Found Control TIs')); - fields.push(renderTiOverview(otherTis, 'Other TIs')); - return fields; -} - -export function remove104Private(doiElement: Element): WizardMenuActor { - return (wizard: Element): void => { - // The 104 Private Element only contains Address Elements, so we can remove all the 104 Private Elements - // to remove all the Address Elements also. - const privateElements = doiElement.querySelectorAll( - `DAI > Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ); - if (privateElements.length > 0) { - const complexAction: ComplexAction = { - actions: [], - title: get('protocol104.values.removedAddresses', { - name: getFullPath(doiElement, 'SCL'), - nrOfAddresses: privateElements.length, - }), - }; - privateElements.forEach(privateElement => { - complexAction.actions.push({ - old: { - parent: privateElement.parentElement!, - element: privateElement, - }, - }); - }); - - wizard.dispatchEvent(newActionEvent(complexAction)); - wizard.dispatchEvent(newWizardEvent()); - } - }; -} - -export function showDOIInfoWizard(doiElement: Element): Wizard { - return [ - { - title: get('protocol104.wizard.title.doiInfo'), - menuActions: [ - { - label: get('protocol104.values.removeAddresses'), - icon: 'delete', - action: remove104Private(doiElement), - }, - ], - content: renderDOIWizard(doiElement), - }, - ]; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/logiclink.ts b/packages/plugins/src/editors/protocol104/wizards/logiclink.ts deleted file mode 100644 index bd8462018b..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/logiclink.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { html } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { pTypesLogicLink104 } from '../foundation/p-types.js'; -import { - getValue, - newWizardEvent, - Wizard, - WizardActor, - WizardInputElement, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement, createElement } from '@openscd/xml'; - -import { - ComplexAction, - EditorAction, - newActionEvent, - SimpleAction, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { createNetworkTextField } from '../foundation/foundation.js'; - -export function editLogicLinkWizard( - parent: Element, - rGNumber: number, - lLNumber: number -): Wizard { - return [ - { - title: get('protocol104.network.logicLink.wizard.title.edit'), - menuActions: [ - { - icon: 'delete', - label: get('remove'), - action: remove(parent, rGNumber, lLNumber), - }, - ], - primary: { - icon: 'save', - label: get('save'), - action: editLogicLinkAction(parent, rGNumber, lLNumber), - }, - content: [ - html` - ${pTypesLogicLink104.map( - pType => - html`${createNetworkTextField( - pType, - parent.querySelector( - `Address > P[type$="RG${rGNumber}-LL${lLNumber}-${pType}"]` - )?.innerHTML - )}` - )}`, - ], - }, - ]; -} - -export function createLogicLinkWizard( - parent: Element, - rGNumber: number, - occupiedLLNumbers: number[] -): Wizard { - // Calculate the first available number for the Logic Link group. - let lLNumber = 1; - while (occupiedLLNumbers.find(n => n == lLNumber)) { - lLNumber++; - } - - return [ - { - title: get('protocol104.network.logicLink.wizard.title.add'), - primary: { - icon: '', - label: get('save'), - action: addLogicLinkAction(parent, rGNumber, lLNumber), - }, - content: [ - html` - ${pTypesLogicLink104.map( - pType => html`${createNetworkTextField(pType)}` - )}`, - ], - }, - ]; -} - -/** - * Remove all P elements belonging to a single Logic Link group. - * @param parent - The parent element of the P elements to remove. - * @param rGNumber - The Redundancy Group number of all the P elements to remove. - * @param lLNumber - The Logic Link Group number of all the P elements to remove. - * @returns - Removing all P elements belonging to a Logic Link group. - */ -function remove( - parent: Element, - rGNumber: number, - lLNumber: number -): WizardMenuActor { - return (wizard: Element): void => { - const addressElement = parent.querySelector('Address'); - - const complexAction: ComplexAction = { - actions: [], - title: get('protocol104.network.logicLink.wizard.removedLogicLink', { - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - }), - }; - - addressElement! - .querySelectorAll(`P[type^="RG${rGNumber}-LL${lLNumber}-"]`) - .forEach(p => { - complexAction.actions.push({ - old: { - parent: addressElement!, - element: p!, - }, - }); - }); - - wizard.dispatchEvent(newActionEvent(complexAction)); - wizard.dispatchEvent(newWizardEvent()); - }; -} - -function editLogicLinkAction( - parent: Element, - rGNumber: number, - lLNumber: number -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const actions: SimpleAction[] = []; - - pTypesLogicLink104.forEach(type => { - const inputValue = getValue(inputs.find(i => i.label === type)!)!; - const elementOriginal = parent.querySelector( - `Address > P[type="RG${rGNumber}-LL${lLNumber}-${type}"]` - ); - - if (elementOriginal == null) { - const element = createElement(parent.ownerDocument, 'P', { - type: `RG${rGNumber}-LL${lLNumber}-${type}`, - }); - element.textContent = getValue(inputs.find(i => i.label === type)!)!; - - actions.push({ - new: { - parent: parent.querySelector('Address')!, - element: element, - }, - }); - } else if (inputValue !== elementOriginal?.textContent) { - const elementClone = cloneElement(elementOriginal!, {}); - elementClone.textContent = inputValue; - - actions.push({ - old: { - element: elementOriginal!, - }, - new: { - element: elementClone, - }, - }); - } - }); - - return actions.length != 0 - ? [ - { - actions, - title: get('protocol104.network.logicLink.wizard.editedLogicLink', { - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - }), - }, - ] - : []; - }; -} - -function addLogicLinkAction( - parent: Element, - rGNumber: number, - lLNumber: number -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const complexAction: ComplexAction = { - actions: [], - title: get('protocol104.network.logicLink.wizard.addedLogicLink', { - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - }), - }; - - pTypesLogicLink104.forEach(type => { - const element = createElement(parent.ownerDocument, 'P', { - type: `RG${rGNumber}-LL${lLNumber}-${type}`, - }); - element.textContent = getValue(inputs.find(i => i.label === type)!)!; - - complexAction.actions.push({ - new: { - parent: parent.querySelector('Address')!, - element: element, - }, - }); - }); - - return [complexAction]; - }; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/redundancygroup.ts b/packages/plugins/src/editors/protocol104/wizards/redundancygroup.ts deleted file mode 100644 index 7b4aba8789..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/redundancygroup.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { html } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { pTypesRedundancyGroup104 } from '../foundation/p-types.js'; -import { - getValue, - newSubWizardEvent, - newWizardEvent, - Wizard, - WizardActor, - WizardInputElement, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; - -import { - cloneElement, - createElement, -} from '@openscd/xml'; - -import { - ComplexAction, - EditorAction, - newActionEvent, - SimpleAction -} from '@openscd/core/foundation/deprecated/editor.js'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; -import { createLogicLinkWizard, editLogicLinkWizard } from './logiclink.js'; -import { - createNetworkTextField, - getTypeAttribute, -} from '../foundation/foundation.js'; - -export function editRedundancyGroupWizard( - parent: Element, - rGNumber: number -): Wizard { - const usedLLNumbers = getLogicLinkNumbers(parent, rGNumber); - return [ - { - title: get('protocol104.network.redundancyGroup.wizard.title.edit'), - menuActions: [ - { - icon: 'playlist_add', - label: get('protocol104.network.redundancyGroup.wizard.addLogicLink'), - action: (wizard: Element): void => { - wizard.dispatchEvent( - newSubWizardEvent( - createLogicLinkWizard(parent, rGNumber, usedLLNumbers) - ) - ); - }, - }, - { - icon: 'delete', - label: get('remove'), - action: remove(parent, rGNumber), - }, - ], - primary: { - icon: 'save', - label: get('save'), - action: editRedundancyGroupAction(parent, rGNumber), - }, - content: [ - html` - ${pTypesRedundancyGroup104.map( - pType => - html`${createNetworkTextField( - pType, - parent.querySelector( - `Address > P[type$="RG${rGNumber}-${pType}"]` - )?.innerHTML - )}` - )} -

- ${get( - 'protocol104.network.redundancyGroup.wizard.logicLinkGroupTitle' - )} -

- { - e.target!.dispatchEvent( - newSubWizardEvent(() => - editLogicLinkWizard( - parent, - rGNumber, - usedLLNumbers[e.detail.index] - ) - ) - ); - }} - > - ${usedLLNumbers.length != 0 - ? usedLLNumbers.map( - number => - html`Logic Link ${number}` - ) - : html`

- ${get( - 'protocol104.network.redundancyGroup.wizard.noLogicLinksAvailable' - )} -

`} -
`, - ], - }, - ]; -} - -export function createRedundancyGroupWizard( - parent: Element, - occupiedRGNumbers: number[] -): Wizard { - // Calculate the first available number for the Logic Link group. - let rGNumber = 1; - while (occupiedRGNumbers.find(n => n == rGNumber)) { - rGNumber++; - } - - return [ - { - title: get('protocol104.network.redundancyGroup.wizard.title.add'), - primary: { - icon: '', - label: get('save'), - action: addRedundancyGroupAction(parent, rGNumber), - }, - content: [ - html` - ${pTypesRedundancyGroup104.map( - pType => html`${createNetworkTextField(pType)}` - )}`, - ], - }, - ]; -} - -/** - * Remove all P elements belonging to a single Redundancy Group. - * @param parent - The parent element of the P elements to remove. - * @param rGNumber - The Redundancy Group number of all the P elements to remove. - * @returns - Removing all P elements belonging to a Redundancy Group. - */ -function remove(parent: Element, rGNumber: number): WizardMenuActor { - return (wizard: Element): void => { - const addressElement = parent.querySelector('Address'); - - const complexAction: ComplexAction = { - actions: [], - title: get( - 'protocol104.network.redundancyGroup.wizard.removedRedundancyGroup', - { - rGNumber, - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - } - ), - }; - - addressElement!.querySelectorAll(`P[type^="RG${rGNumber}-"]`).forEach(p => { - complexAction.actions.push({ - old: { - parent: addressElement!, - element: p!, - }, - }); - }); - - wizard.dispatchEvent(newActionEvent(complexAction)); - wizard.dispatchEvent(newWizardEvent()); - }; -} - -function editRedundancyGroupAction( - parent: Element, - rGNumber: number -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const actions: SimpleAction[] = []; - - pTypesRedundancyGroup104.forEach(type => { - const inputValue = getValue(inputs.find(i => i.label === type)!)!; - const elementOriginal = parent.querySelector( - `Address > P[type="RG${rGNumber}-${type}"]` - ); - - if (elementOriginal == null) { - const pElement = createElement(parent.ownerDocument, 'P', { - type: `RG${rGNumber}-${type}`, - }); - pElement.textContent = inputValue; - - actions.push({ - new: { - parent: parent.querySelector('Address')!, - element: pElement, - }, - }); - } else if (inputValue !== elementOriginal?.textContent) { - const elementClone = cloneElement(elementOriginal!, {}); - elementClone.textContent = inputValue; - - actions.push({ - old: { - element: elementOriginal!, - }, - new: { - element: elementClone, - }, - }); - } - }); - - return actions.length != 0 - ? [ - { - actions, - title: get( - 'protocol104.network.redundancyGroup.wizard.editedRedundancyGroup', - { - rGNumber, - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - } - ), - }, - ] - : []; - }; -} - -function addRedundancyGroupAction( - parent: Element, - rGNumber: number -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const complexAction: ComplexAction = { - actions: [], - title: get( - 'protocol104.network.redundancyGroup.wizard.addedLRedundancyGroup', - { - rGNumber, - subNetworkName: parent.parentElement!.getAttribute('name')!, - apName: parent.getAttribute('apName')!, - iedName: parent.getAttribute('iedName')!, - } - ), - }; - - pTypesRedundancyGroup104.forEach(type => { - const pElement = createElement(parent.ownerDocument, 'P', { - type: `RG${rGNumber}-${type}`, - }); - pElement.textContent = getValue(inputs.find(i => i.label === type)!)!; - - complexAction.actions.push({ - new: { - parent: parent.querySelector('Address')!, - element: pElement, - }, - }); - }); - - return [complexAction]; - }; -} - -/** - * Get all the current used Logic Link numbers. - * @param parent - The parent element of all the P elements. - * @param rGNumber - The Redundancy Group number to use for searching Logic Link groups. - * @returns An array with all the Logic Link group numbers. - */ -function getLogicLinkNumbers(parent: Element, rGNumber: number): number[] { - const usedNumbers: number[] = []; - - parent - .querySelectorAll(`Address > P[type^="RG${rGNumber}-LL"]`) - .forEach(p => { - const logicLinkPart = getTypeAttribute(p)?.split('-')[1]; - const number = Number(logicLinkPart?.substring(2)); - - if (!usedNumbers.includes(number)) usedNumbers.push(number); - }); - - return usedNumbers.sort(); -} diff --git a/packages/plugins/src/editors/protocol104/wizards/selectDo.ts b/packages/plugins/src/editors/protocol104/wizards/selectDo.ts deleted file mode 100644 index 1f8c0dd3c3..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/selectDo.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@openscd/open-scd/src/finder-list.js'; - -import { - getDisplayString, - getReader, -} from '../../../wizards/foundation/finder.js'; -import { FinderList, Path } from '@openscd/open-scd/src/finder-list.js'; -import { - compareNames, - getNameAttribute, - identity, - newSubWizardEvent, - find, - Wizard, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { createAddressesWizard } from './createAddresses.js'; -import { SupportedCdcType, supportedCdcTypes } from '../foundation/cdc.js'; -import { PROTOCOL_104_PRIVATE } from '../foundation/private.js'; -import { - getCdcValueFromDOElement, - getDoElements, -} from '../foundation/foundation.js'; - -/** - * Check if the passed DO Element is supported by the 104 protocol and isn't initiated. - * - * @param lnElement - The LN Element used to search for Address Element below DOI, if available. - * @param doElement - The DO Element to check. - */ -function filterAvailableDOElements( - lnElement: Element, - doElement: Element -): boolean { - // First check if this DO Element is supported by the 104 Protocol. - const cdc = getCdcValueFromDOElement(doElement) ?? ''; - if (!supportedCdcTypes.includes(cdc)) { - return false; - } - - // Use the parent (LN) to find the DOI that's linked to the DO Element - // And check if there is DOI if it doesn't already contain Address Elements for the 104 Protocol. - const doName = getNameAttribute(doElement); - return ( - lnElement.querySelectorAll( - `:scope > DOI[name="${doName}"] DAI > Private[type="${PROTOCOL_104_PRIVATE}"] > Address` - ).length <= 0 - ); -} - -/** - * Check if there are DO Elements that aren't initiated and are supported by the 104 protocol. If this is the - * case the Element can be shown in the Finder. - * - * @param child - The child to check if it should still be displayed in the finder list. - */ -function filterAvailableElements(child: Element): boolean { - // For other elements create a list of LN Elements for processing the DO Element from the LN Elements. - let lnElements: Element[]; - if (['LN0', 'LN'].includes(child.tagName)) { - lnElements = [child]; - } else { - // For the other Elements we will just retrieve all the DOI Elements. - lnElements = Array.from(child.querySelectorAll('LN0, LN')); - } - - // If after filtering there are still LN/DO Element(s) to be displayed, this element will be included. - return ( - lnElements.filter( - lnElement => - // Check if there are available DO Elements that aren't initiated and supported by 104 protocol - getDoElements(lnElement).filter(doElement => - filterAvailableDOElements(lnElement, doElement) - ).length > 0 - ).length > 0 - ); -} - -/** - * Retrieve the Data Children needed for the filter-list to display, the elements shown are - * 'IED' -> 'AccessPoint' -> 'LDevice' -> 'LN(0)' -> 'DO'. - * - * @param parent - The previous element selected, starting with SCL Element. - */ -export function getDataChildren(parent: Element): Element[] { - let children; - if (['LN0', 'LN'].includes(parent.tagName)) { - // For LN Element we will not search for the children, but the DO Element linked to LN from the Template Section. - const lnType = parent.getAttribute('lnType') ?? ''; - children = Array.from( - parent.ownerDocument.querySelectorAll( - `:root > DataTypeTemplates > LNodeType[id="${lnType}"] > DO` - ) - ) - .filter(child => filterAvailableDOElements(parent, child)) - .sort((a, b) => compareNames(`${identity(a)}`, `${identity(b)}`)); - } else if (parent.tagName === 'AccessPoint') { - // From the Access Point we will skip directly to the LDevice Element and skip the Server element. - // Or retrieve the LN Elements directly below the AccessPoint. - children = Array.from(parent.querySelectorAll('LDevice, :scope > LN')) - .filter(child => filterAvailableElements(child)) - .sort((a, b) => compareNames(`${identity(a)}`, `${identity(b)}`)); - } else { - // The other element, just retrieve the children and if the tagName is one we need return that child. - children = Array.from(parent.children) - .filter(child => - ['IED', 'AccessPoint', 'LN0', 'LN'].includes(child.tagName) - ) - .filter(child => filterAvailableElements(child)) - .sort((a, b) => compareNames(`${identity(a)}`, `${identity(b)}`)); - } - - return children; -} - -/** - * Action executed when 'next' is pressed. It will start the 'create address'-wizard when a DO Element - * is selected, otherwise nothing happens. - * - * @param doc - The XML Document loaded to search element in. - */ -function openPrepareAddressWizard(doc: XMLDocument): WizardActor { - return (_: WizardInputElement[], wizard: Element) => { - const finder = wizard.shadowRoot?.querySelector('finder-list'); - const path = finder?.path ?? []; - - if (path.length === 0) return []; - - const doElement = checkAndGetLastElementFromPath(doc, path, ['DO']); - const lnElement = checkAndGetLastElementFromPath(doc, path, ['LN0', 'LN']); - - if (lnElement && doElement) { - wizard.dispatchEvent( - newSubWizardEvent(createAddressesWizard(lnElement, doElement)) - ); - } - return []; - }; -} - -/** - * Simple function to retrieve the next element from the path selected. - * Also check if that element is the expected element. - * - * @param doc - The XML Document to be used for querying. - * @param path - The array of selected element to pop the last element name from. - * @param expectedTag - The tagname expected to be found when popping the lats element. - */ -function checkAndGetLastElementFromPath( - doc: XMLDocument, - path: Path, - expectedTag: string[] -): Element | null { - const [tagName, id] = path.pop()!.split(': '); - if (!expectedTag.includes(tagName)) return null; - - return find(doc, tagName, id); -} - -/** - * Start a Finder List to select a DO that can be initiated to be used for the 104 protocol. - * - * @param doc - The XML Document loaded. - * @returns The Wizard to be displayed in a dialog. - */ -export function selectDoWizard(doc: Document): Wizard { - function renderTemplate(doc: XMLDocument): TemplateResult { - return html` path[path.length - 1]} - > - `; - } - - return [ - { - title: get('wizard.title.select', { tagName: 'DO(I)' }), - primary: { - icon: '', - label: get('next'), - action: openPrepareAddressWizard(doc), - }, - content: [renderTemplate(doc)], - }, - ]; -} diff --git a/packages/plugins/src/editors/protocol104/wizards/subnetwork.ts b/packages/plugins/src/editors/protocol104/wizards/subnetwork.ts deleted file mode 100644 index 6825c59b02..0000000000 --- a/packages/plugins/src/editors/protocol104/wizards/subnetwork.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; -import { - getMultiplier, - getValue, - patterns, - Wizard, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; - -import { createElement } from '@openscd/xml'; - -import { EditorAction } from '@openscd/core/foundation/deprecated/editor'; - -import '@openscd/open-scd/src/wizard-textfield.js'; - -/** Initial attribute values suggested for `SubNetwork` creation for the 104 plugin */ -const initial = { - type: '104', - bitrate: '100', - multiplier: 'M', -}; - -interface ContentOptions { - name: string | null; - desc: string | null; - type: string | null; - BitRate: string | null; - multiplier: string | null; -} - -function contentSubNetwork(options: ContentOptions): TemplateResult[] { - return [ - html``, - html``, - html``, - html``, - ]; -} - -export function createSubNetworkAction(parent: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const name = getValue(inputs.find(i => i.label === 'name')!); - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const type = getValue(inputs.find(i => i.label === 'type')!); - const BitRate = getValue(inputs.find(i => i.label === 'BitRate')!); - const multiplier = getMultiplier(inputs.find(i => i.label === 'BitRate')!); - - const element = createElement(parent.ownerDocument, 'SubNetwork', { - name, - desc, - type, - }); - - if (BitRate !== null) { - const bitRateElement = createElement(parent.ownerDocument, 'BitRate', { - unit: 'b/s', - multiplier, - }); - bitRateElement.textContent = BitRate; - element.appendChild(bitRateElement); - } - - const action = { - new: { - parent, - element, - }, - }; - - return [action]; - }; -} - -export function createSubNetworkWizard(parent: Element): Wizard { - return [ - { - title: get('wizard.title.add', { tagName: 'SubNetwork' }), - primary: { - icon: 'add', - label: get('add'), - action: createSubNetworkAction(parent), - }, - content: contentSubNetwork({ - name: '', - desc: '', - type: initial.type, - BitRate: initial.bitrate, - multiplier: initial.multiplier, - }), - }, - ]; -} diff --git a/packages/plugins/src/editors/publisher/data-set-editor.ts b/packages/plugins/src/editors/publisher/data-set-editor.ts deleted file mode 100644 index 6d77dc0b65..0000000000 --- a/packages/plugins/src/editors/publisher/data-set-editor.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - query, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list/mwc-list-item'; -import { Button } from '@material/mwc-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import './data-set-element-editor.js'; -import '@openscd/open-scd/src/filtered-list.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; - -import { - compareNames, - identity, - find, -} from '@openscd/open-scd/src/foundation.js'; -import { styles, updateElementReference } from './foundation.js'; - -@customElement('data-set-editor') -export class DataSetEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - - @state() - selectedDataSet?: Element; - - @query('.selectionlist') selectionList!: FilteredList; - @query('mwc-button') selectDataSetButton!: Button; - - /** Resets selected GOOSE, if not existing in new doc */ - update(props: Map): void { - if (props.has('doc') && this.selectedDataSet) { - const newDataSet = updateElementReference(this.doc, this.selectedDataSet); - - this.selectedDataSet = newDataSet ?? undefined; - - if (!newDataSet && this.selectionList && this.selectionList.selected) - (this.selectionList.selected as ListItem).selected = false; - } - - super.update(props); - } - - private selectDataSet(evt: Event): void { - const id = ((evt.target as FilteredList).selected as ListItem).value; - const dataSet = find(this.doc, 'DataSet', id); - - if (dataSet) { - this.selectedDataSet = dataSet; - (evt.target as FilteredList).classList.add('hidden'); - this.selectDataSetButton.classList.remove('hidden'); - } - } - - private renderElementEditorContainer(): TemplateResult { - if (this.selectedDataSet) - return html`
- -
`; - - return html``; - } - - private renderSelectionList(): TemplateResult { - return html`${Array.from(this.doc.querySelectorAll('IED')) - .sort(compareNames) - .flatMap(ied => { - const ieditem = html` - ${ied.getAttribute('name')} - developer_board - -
  • `; - - const dataSets = Array.from(ied.querySelectorAll('DataSet')).map( - dataSet => - html`${dataSet.getAttribute('name')}${identity(dataSet)} - ` - ); - - return [ieditem, ...dataSets]; - })}
    `; - } - - private renderToggleButton(): TemplateResult { - return html` { - this.selectionList.classList.remove('hidden'); - this.selectDataSetButton.classList.add('hidden'); - }} - >`; - } - - render(): TemplateResult { - return html`${this.renderToggleButton()} -
    - ${this.renderSelectionList()}${this.renderElementEditorContainer()} -
    `; - } - - static styles = css` - ${styles} - - data-set-element-editor { - flex: auto; - } - `; -} diff --git a/packages/plugins/src/editors/publisher/data-set-element-editor.ts b/packages/plugins/src/editors/publisher/data-set-element-editor.ts deleted file mode 100644 index 874002c363..0000000000 --- a/packages/plugins/src/editors/publisher/data-set-element-editor.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import '@openscd/open-scd/src/filtered-list.js'; - -import { identity } from '@openscd/open-scd/src/foundation.js'; - -@customElement('data-set-element-editor') -export class DataSetElementEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - /** The element being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - element!: Element | null; - - @state() - private get name(): string | null { - return this.element ? this.element.getAttribute('name') : 'UNDEFINED'; - } - @state() - private get desc(): string | null { - return this.element ? this.element.getAttribute('desc') : 'UNDEFINED'; - } - - private renderContent(): TemplateResult { - return html` - - - - ${Array.from(this.element!.querySelectorAll('FCDA')).map(fcda => { - const [ldInst, prefix, lnClass, lnInst, doName, daName, fc] = [ - 'ldInst', - 'prefix', - 'lnClass', - 'lnInst', - 'doName', - 'daName', - 'fc', - ].map(attributeName => fcda.getAttribute(attributeName) ?? ''); - - return html`${doName}${daName - ? '.' + daName + ' ' + '[' + fc + ']' - : ' ' + '[' + fc + ']'}${ldInst + '/' + prefix + lnClass + lnInst} - `; - })}`; - } - - render(): TemplateResult { - if (this.element) - return html`
    -

    -
    DataSet
    -
    ${identity(this.element)}
    -

    - ${this.renderContent()} -
    `; - - return html`
    -

    -
    DataSet
    -
    ${get('publisher.nodataset')}
    -

    -
    `; - } - - static styles = css` - .content { - display: flex; - flex-direction: column; - background-color: var(--mdc-theme-surface); - } - - .content > * { - display: block; - margin: 4px 8px 16px; - } - - h2 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - - margin: 0px; - padding-left: 0.3em; - transition: background-color 150ms linear; - } - - .headersubtitle { - font-size: 16px; - font-weight: 200; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - *[iconTrailing='search'] { - --mdc-shape-small: 28px; - } - `; -} diff --git a/packages/plugins/src/editors/publisher/foundation.ts b/packages/plugins/src/editors/publisher/foundation.ts deleted file mode 100644 index fe2ed4ef24..0000000000 --- a/packages/plugins/src/editors/publisher/foundation.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { css } from 'lit-element'; - -import { identity, find } from '@openscd/open-scd/src/foundation.js'; - -export function updateElementReference( - newDoc: XMLDocument, - oldElement: Element -): Element | null { - if (!oldElement || !oldElement.closest('SCL')) return null; - - const id = identity(oldElement); - const newElement = find(newDoc, oldElement.tagName, id); - - return newElement; -} - -export const styles = css` - .content { - display: flex; - height: calc(100vh - 184px); - } - - .selectionlist { - flex: 35%; - margin: 4px 4px 4px 8px; - background-color: var(--mdc-theme-surface); - overflow-y: scroll; - } - - .elementeditorcontainer { - flex: 65%; - margin: 4px 8px 4px 4px; - background-color: var(--mdc-theme-surface); - overflow-y: scroll; - display: flex; - } - - .listitem.header { - font-weight: 500; - } - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - - mwc-button { - display: none; - } - - @media (max-width: 950px) { - .elementeditorcontainer { - display: block; - } - } - - @media (max-width: 599px) { - .content { - height: 100%; - } - - .selectionlist { - position: absolute; - width: calc(100% - 32px); - height: auto; - top: 110px; - left: 8px; - background-color: var(--mdc-theme-surface); - z-index: 1; - box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); - } - - .elementeditorcontainer { - display: block; - } - - data-set-element-editor { - width: calc(100% - 16px); - } - - .selectionlist.hidden { - display: none; - } - - mwc-button { - display: flex; - margin: 4px 8px 8px; - } - } -`; diff --git a/packages/plugins/src/editors/publisher/gse-control-editor.ts b/packages/plugins/src/editors/publisher/gse-control-editor.ts deleted file mode 100644 index 99ac9bd777..0000000000 --- a/packages/plugins/src/editors/publisher/gse-control-editor.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - state, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list/mwc-list-item'; -import { Button } from '@material/mwc-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import './data-set-element-editor.js'; -import './gse-control-element-editor.js'; -import '@openscd/open-scd/src/filtered-list.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; - -import { gooseIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { - compareNames, - identity, - find, -} from '@openscd/open-scd/src/foundation.js'; -import { styles, updateElementReference } from './foundation.js'; - -@customElement('gse-control-editor') -export class GseControlEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @state() - selectedGseControl?: Element; - @state() - selectedDataSet?: Element | null; - - @query('.selectionlist') selectionList!: FilteredList; - @query('mwc-button') selectGSEControlButton!: Button; - - /** Resets selected GOOSE and its DataSet, if not existing in new doc */ - update(props: Map): void { - if (props.has('doc') && this.selectedGseControl) { - const newGseControl = updateElementReference( - this.doc, - this.selectedGseControl - ); - - this.selectedGseControl = newGseControl ?? undefined; - this.selectedDataSet = this.selectedGseControl - ? updateElementReference(this.doc, this.selectedDataSet!) - : undefined; - - if (!newGseControl && this.selectionList && this.selectionList.selected) - (this.selectionList.selected as ListItem).selected = false; - } - - super.update(props); - } - - private selectGSEControl(evt: Event): void { - const id = ((evt.target as FilteredList).selected as ListItem).value; - const gseControl = find(this.doc, 'GSEControl', id); - if (!gseControl) return; - - this.selectedGseControl = gseControl; - - if (gseControl) { - this.selectedDataSet = gseControl.parentElement?.querySelector( - `DataSet[name="${gseControl.getAttribute('datSet')}"]` - ); - (evt.target as FilteredList).classList.add('hidden'); - this.selectGSEControlButton.classList.remove('hidden'); - } - } - - private renderElementEditorContainer(): TemplateResult { - if (this.selectedGseControl !== undefined) - return html`
    - - -
    `; - - return html``; - } - - renderSelectionList(): TemplateResult { - return html`${Array.from(this.doc.querySelectorAll('IED')) - .sort(compareNames) - .flatMap(ied => { - const ieditem = html` - ${ied.getAttribute('name')} - developer_board - -
  • `; - - const gseControls = Array.from( - ied.querySelectorAll('GSEControl') - ).map( - reportCb => - html`${reportCb.getAttribute('name')}${identity(reportCb)} - ${gooseIcon} - ` - ); - - return [ieditem, ...gseControls]; - })}
    `; - } - - private renderToggleButton(): TemplateResult { - return html` { - this.selectionList.classList.remove('hidden'); - this.selectGSEControlButton.classList.add('hidden'); - }} - >`; - } - - render(): TemplateResult { - return html`${this.renderToggleButton()} -
    - ${this.renderSelectionList()}${this.renderElementEditorContainer()} -
    `; - } - - static styles = css` - ${styles} - - .elementeditorcontainer { - flex: 65%; - margin: 4px 8px 4px 4px; - background-color: var(--mdc-theme-surface); - overflow-y: scroll; - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - grid-template-columns: repeat(3, 1fr); - } - - data-set-element-editor { - grid-column: 1 / 2; - } - - gse-control-element-editor { - grid-column: 2 / 4; - } - - @media (max-width: 950px) { - .elementeditorcontainer { - display: block; - } - } - `; -} diff --git a/packages/plugins/src/editors/publisher/gse-control-element-editor.ts b/packages/plugins/src/editors/publisher/gse-control-element-editor.ts deleted file mode 100644 index 638694ac17..0000000000 --- a/packages/plugins/src/editors/publisher/gse-control-element-editor.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-formfield'; -import '@material/mwc-checkbox'; - -import '@openscd/open-scd/src/wizard-checkbox.js'; -import '@openscd/open-scd/src/wizard-select.js'; -import '@openscd/open-scd/src/wizard-textfield.js'; - -import { identity } from '@openscd/open-scd/src/foundation.js'; -import { maxLength, patterns } from '../../wizards/foundation/limits.js'; -import { typeNullable, typePattern } from '../../wizards/foundation/p-types.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; - -@customElement('gse-control-element-editor') -export class GseControlElementEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - /** The element being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - element!: Element; - @property({ attribute: false }) - get gSE(): Element | null | undefined { - const cbName = this.element.getAttribute('name'); - const iedName = this.element.closest('IED')?.getAttribute('name'); - const apName = this.element.closest('AccessPoint')?.getAttribute('name'); - const ldInst = this.element.closest('LDevice')?.getAttribute('inst'); - - return this.element.ownerDocument.querySelector( - `:root > Communication > SubNetwork > ` + - `ConnectedAP[iedName="${iedName}"][apName="${apName}"] > ` + - `GSE[ldInst="${ldInst}"][cbName="${cbName}"]` - ); - } - - private renderGseContent(): TemplateResult { - const gSE = this.gSE; - if (!gSE) - return html`
    -

    -
    Communication Settings (GSE)
    -
    No connection to SubNetwork
    -

    -
    `; - - const minTime = gSE.querySelector('MinTime')?.innerHTML.trim() ?? null; - const maxTime = gSE.querySelector('MaxTime')?.innerHTML.trim() ?? null; - - const hasInstType = Array.from(gSE.querySelectorAll('Address > P')).some( - pType => pType.getAttribute('xsi:type') - ); - - const attributes: Record = {}; - - ['MAC-Address', 'APPID', 'VLAN-ID', 'VLAN-PRIORITY'].forEach(key => { - if (!attributes[key]) - attributes[key] = - gSE.querySelector(`Address > P[type="${key}"]`)?.innerHTML.trim() ?? - null; - }); - - return html`
    -

    Communication Settings (GSE)

    - ${Object.entries(attributes).map( - ([key, value]) => - html`` - )} -
    `; - } - - private renderGseControlContent(): TemplateResult { - const [name, desc, type, appID, fixedOffs, securityEnabled] = [ - 'name', - 'desc', - 'type', - 'appID', - 'fixedOffs', - 'securityEnabled', - ].map(attr => this.element?.getAttribute(attr)); - - return html`
    - - - ${['GOOSE', 'GSSE'].map( - type => html`${type}` - )} - - - ${['None', 'Signature', 'SignatureAndEncryption'].map( - type => html`${type}` - )} -
    `; - } - - render(): TemplateResult { - return html`

    -
    -
    GSEControl
    -
    ${identity(this.element)}
    -
    -

    -
    - ${this.renderGseControlContent()}${this.renderGseContent()} -
    `; - } - - static styles = css` - .parentcontent { - display: grid; - grid-gap: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - .content { - border-left: thick solid var(--mdc-theme-on-primary); - } - - .content > * { - display: block; - margin: 4px 8px 16px; - } - - h2, - h3 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - margin: 4px 8px 16px; - padding-left: 0.3em; - } - - .headersubtitle { - font-size: 16px; - font-weight: 200; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - *[iconTrailing='search'] { - --mdc-shape-small: 28px; - } - - @media (max-width: 950px) { - .content { - border-left: 0px solid var(--mdc-theme-on-primary); - } - } - `; -} diff --git a/packages/plugins/src/editors/publisher/report-control-editor.ts b/packages/plugins/src/editors/publisher/report-control-editor.ts deleted file mode 100644 index 70ed82469a..0000000000 --- a/packages/plugins/src/editors/publisher/report-control-editor.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - query, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list/mwc-list-item'; -import { Button } from '@material/mwc-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import './data-set-element-editor.js'; -import './report-control-element-editor.js'; -import '@openscd/open-scd/src/filtered-list.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; - -import { - compareNames, - identity, - find, -} from '@openscd/open-scd/src/foundation.js'; -import { reportIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { styles, updateElementReference } from './foundation.js'; - -@customElement('report-control-editor') -export class ReportControlEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @state() - selectedReportControl?: Element; - @state() - selectedDataSet?: Element | null; - - @query('.selectionlist') selectionList!: FilteredList; - @query('mwc-button') selectReportControlButton!: Button; - - /** Resets selected Report and its DataSet, if not existing in new doc */ - update(props: Map): void { - if (props.has('doc') && this.selectedReportControl) { - const newReportControl = updateElementReference( - this.doc, - this.selectedReportControl - ); - - this.selectedReportControl = newReportControl ?? undefined; - this.selectedDataSet = this.selectedReportControl - ? updateElementReference(this.doc, this.selectedDataSet!) - : undefined; - - if ( - !newReportControl && - this.selectionList && - this.selectionList.selected - ) - (this.selectionList.selected as ListItem).selected = false; - } - - super.update(props); - } - - private selectReportControl(evt: Event): void { - const id = ((evt.target as FilteredList).selected as ListItem).value; - const reportControl = find(this.doc, 'ReportControl', id); - if (!reportControl) return; - - this.selectedReportControl = reportControl; - - if (this.selectedReportControl) { - this.selectedDataSet = - this.selectedReportControl.parentElement?.querySelector( - `DataSet[name="${this.selectedReportControl.getAttribute('datSet')}"]` - ); - (evt.target as FilteredList).classList.add('hidden'); - this.selectReportControlButton.classList.remove('hidden'); - } - } - - private renderElementEditorContainer(): TemplateResult { - if (this.selectedReportControl !== undefined) - return html`
    - - -
    `; - - return html``; - } - - private renderSelectionList(): TemplateResult { - return html`${Array.from(this.doc.querySelectorAll('IED')) - .sort(compareNames) - .flatMap(ied => { - const ieditem = html` - ${ied.getAttribute('name')} - developer_board - -
  • `; - - const reports = Array.from(ied.querySelectorAll('ReportControl')).map( - reportCb => - html`${reportCb.getAttribute('name')}${identity(reportCb)} - ${reportIcon} - ` - ); - - return [ieditem, ...reports]; - })}
    `; - } - - private renderToggleButton(): TemplateResult { - return html` { - this.selectionList.classList.remove('hidden'); - this.selectReportControlButton.classList.add('hidden'); - }} - >`; - } - - render(): TemplateResult { - return html`${this.renderToggleButton()} -
    - ${this.renderSelectionList()}${this.renderElementEditorContainer()} -
    `; - } - - static styles = css` - ${styles} - - .elementeditorcontainer { - flex: 65%; - margin: 4px 8px 4px 4px; - background-color: var(--mdc-theme-surface); - overflow-y: scroll; - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - grid-template-columns: repeat(3, 1fr); - } - - data-set-element-editor { - grid-column: 1 / 2; - } - - report-control-element-editor { - grid-column: 2 / 4; - } - - @media (max-width: 950px) { - .elementeditorcontainer { - display: block; - } - } - `; -} diff --git a/packages/plugins/src/editors/publisher/report-control-element-editor.ts b/packages/plugins/src/editors/publisher/report-control-element-editor.ts deleted file mode 100644 index c16b7a3571..0000000000 --- a/packages/plugins/src/editors/publisher/report-control-element-editor.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import '@openscd/open-scd/src/wizard-checkbox.js'; - -import { identity } from '@openscd/open-scd/src/foundation.js'; -import { maxLength, patterns } from '../../wizards/foundation/limits.js'; - -@customElement('report-control-element-editor') -export class ReportControlElementEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - /** The element being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - element!: Element; - - private renderOptFieldsContent(): TemplateResult { - const [ - seqNum, - timeStamp, - dataSet, - reasonCode, - dataRef, - entryID, - configRef, - bufOvfl, - ] = [ - 'seqNum', - 'timeStamp', - 'dataSet', - 'reasonCode', - 'dataRef', - 'entryID', - 'configRef', - 'bufOvfl', - ].map( - attr => - this.element.querySelector('OptFields')?.getAttribute(attr) ?? null - ); - - return html`

    Optional Fields

    - ${Object.entries({ - seqNum, - timeStamp, - dataSet, - reasonCode, - dataRef, - entryID, - configRef, - bufOvfl, - }).map( - ([key, value]) => - html`` - )}`; - } - - private renderTrgOpsContent(): TemplateResult { - const [dchg, qchg, dupd, period, gi] = [ - 'dchg', - 'qchg', - 'dupd', - 'period', - 'gi', - ].map( - attr => this.element.querySelector('TrgOps')?.getAttribute(attr) ?? null - ); - - return html`

    Trigger Options

    - ${Object.entries({ dchg, qchg, dupd, period, gi }).map( - ([key, value]) => - html`` - )}`; - } - - private renderChildElements(): TemplateResult { - return html`
    - ${this.renderTrgOpsContent()}${this.renderOptFieldsContent()} -
    `; - } - - private renderReportControlContent(): TemplateResult { - const [name, desc, buffered, rptID, indexed, bufTime, intgPd] = [ - 'name', - 'desc', - 'buffered', - 'rptID', - 'indexed', - 'bufTime', - 'intgPd', - ].map(attr => this.element?.getAttribute(attr)); - const max = - this.element.querySelector('RptEnabled')?.getAttribute('max') ?? null; - - return html`
    - -
    `; - } - - render(): TemplateResult { - if (this.element) - return html`

    -
    -
    ReportControl
    -
    ${identity(this.element)}
    -
    -

    -
    - ${this.renderReportControlContent()}${this.renderChildElements()} -
    `; - - return html`
    -

    ${get('publisher.nodataset')}

    -
    `; - } - - static styles = css` - .parentcontent { - display: grid; - grid-gap: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - .content { - border-left: thick solid var(--mdc-theme-on-primary); - } - - .content > * { - display: block; - margin: 4px 8px 16px; - } - - h2, - h3 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - margin: 4px 8px 16px; - padding-left: 0.3em; - } - - .headersubtitle { - font-size: 16px; - font-weight: 200; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - *[iconTrailing='search'] { - --mdc-shape-small: 28px; - } - - @media (max-width: 950px) { - .content { - border-left: 0px solid var(--mdc-theme-on-primary); - } - } - `; -} diff --git a/packages/plugins/src/editors/publisher/sampled-value-control-editor.ts b/packages/plugins/src/editors/publisher/sampled-value-control-editor.ts deleted file mode 100644 index a734b29bfb..0000000000 --- a/packages/plugins/src/editors/publisher/sampled-value-control-editor.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - query, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list/mwc-list-item'; -import { Button } from '@material/mwc-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import './data-set-element-editor.js'; -import '@openscd/open-scd/src/filtered-list.js'; -import './sampled-value-control-element-editor.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; - -import { - compareNames, - identity, - find, -} from '@openscd/open-scd/src/foundation.js'; -import { smvIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { styles, updateElementReference } from './foundation.js'; - -@customElement('sampled-value-control-editor') -export class SampledValueControlEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @state() - selectedSampledValueControl?: Element; - @state() - selectedDataSet?: Element | null; - - @query('.selectionlist') selectionList!: FilteredList; - @query('mwc-button') selectSampledValueControlButton!: Button; - - /** Resets selected SMV and its DataSet, if not existing in new doc */ - update(props: Map): void { - if (props.has('doc') && this.selectedSampledValueControl) { - const newSampledValueControl = updateElementReference( - this.doc, - this.selectedSampledValueControl - ); - - this.selectedSampledValueControl = newSampledValueControl ?? undefined; - this.selectedDataSet = this.selectedSampledValueControl - ? updateElementReference(this.doc, this.selectedDataSet!) - : undefined; - - if ( - !newSampledValueControl && - this.selectionList && - this.selectionList.selected - ) - (this.selectionList.selected as ListItem).selected = false; - } - - super.update(props); - } - - private selectSMVControl(evt: Event): void { - const id = ((evt.target as FilteredList).selected as ListItem).value; - const smvControl = find(this.doc, 'SampledValueControl', id); - if (!smvControl) return; - - this.selectedSampledValueControl = smvControl; - - if (smvControl) { - this.selectedDataSet = - smvControl.parentElement?.querySelector( - `DataSet[name="${smvControl.getAttribute('datSet')}"]` - ) ?? null; - (evt.target as FilteredList).classList.add('hidden'); - this.selectSampledValueControlButton.classList.remove('hidden'); - } - } - - private renderElementEditorContainer(): TemplateResult { - if (this.selectedSampledValueControl !== undefined) - return html`
    - - -
    `; - - return html``; - } - - private renderSelectionList(): TemplateResult { - return html`${Array.from(this.doc.querySelectorAll('IED')) - .sort(compareNames) - .flatMap(ied => { - const ieditem = html` - ${ied.getAttribute('name')} - developer_board - -
  • `; - - const sampledValueControls = Array.from( - ied.querySelectorAll('SampledValueControl') - ).map( - reportCb => - html`${reportCb.getAttribute('name')}${identity(reportCb)} - ${smvIcon} - ` - ); - - return [ieditem, ...sampledValueControls]; - })}
    `; - } - - private renderToggleButton(): TemplateResult { - return html` { - this.selectionList.classList.remove('hidden'); - this.selectSampledValueControlButton.classList.add('hidden'); - }} - >`; - } - - render(): TemplateResult { - return html`${this.renderToggleButton()} -
    - ${this.renderSelectionList()}${this.renderElementEditorContainer()} -
    `; - } - - static styles = css` - ${styles} - - .elementeditorcontainer { - flex: 65%; - margin: 4px 8px 4px 4px; - background-color: var(--mdc-theme-surface); - overflow-y: scroll; - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - grid-template-columns: repeat(3, 1fr); - } - - data-set-element-editor { - grid-column: 1 / 2; - } - - sampled-value-control-element-editor { - grid-column: 2 / 4; - } - - @media (max-width: 950px) { - .elementeditorcontainer { - display: block; - } - } - `; -} diff --git a/packages/plugins/src/editors/publisher/sampled-value-control-element-editor.ts b/packages/plugins/src/editors/publisher/sampled-value-control-element-editor.ts deleted file mode 100644 index f12f2deaed..0000000000 --- a/packages/plugins/src/editors/publisher/sampled-value-control-element-editor.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-formfield'; -import '@material/mwc-checkbox'; - -import '@openscd/open-scd/src/wizard-checkbox.js'; -import '@openscd/open-scd/src/wizard-select.js'; -import '@openscd/open-scd/src/wizard-textfield.js'; - -import { identity } from '@openscd/open-scd/src/foundation.js'; -import { maxLength, patterns } from '../../wizards/foundation/limits.js'; -import { typeNullable, typePattern } from '../../wizards/foundation/p-types.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; - -@customElement('sampled-value-control-element-editor') -export class SampledValueControlElementEditor extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - /** The element being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) - element!: Element; - @property({ attribute: false }) - get sMV(): Element | null { - const cbName = this.element.getAttribute('name'); - const iedName = this.element.closest('IED')?.getAttribute('name'); - const apName = this.element.closest('AccessPoint')?.getAttribute('name'); - const ldInst = this.element.closest('LDevice')?.getAttribute('inst'); - - return this.element.ownerDocument.querySelector( - `:root > Communication > SubNetwork > ` + - `ConnectedAP[iedName="${iedName}"][apName="${apName}"] > ` + - `SMV[ldInst="${ldInst}"][cbName="${cbName}"]` - ); - } - - private renderSmvContent(): TemplateResult { - const sMV = this.sMV; - if (!sMV) - return html`

    -
    ${get('publisher.smv.commsetting')}
    -
    ${get('publisher.smv.noconnectionap')}
    -

    `; - - const hasInstType = Array.from(sMV.querySelectorAll('Address > P')).some( - pType => pType.getAttribute('xsi:type') - ); - - const attributes: Record = {}; - - ['MAC-Address', 'APPID', 'VLAN-ID', 'VLAN-PRIORITY'].forEach(key => { - if (!attributes[key]) - attributes[key] = - sMV - .querySelector(`Address > P[type="${key}"]`) - ?.textContent?.trim() ?? null; - }); - - return html`

    ${get('publisher.smv.commsetting')}

    - ${Object.entries(attributes).map( - ([key, value]) => - html`` - )}`; - } - - private renderSmvOptsContent(): TemplateResult { - const [refreshTime, sampleRate, dataSet, security, synchSourceId] = [ - 'refreshTime', - 'sampleRate', - 'dataSet', - 'security', - 'synchSourceId', - ].map( - attr => this.element.querySelector('SmvOpts')?.getAttribute(attr) ?? null - ); - - return html`

    ${get('publisher.smv.smvopts')}

    - ${Object.entries({ - refreshTime, - sampleRate, - dataSet, - security, - synchSourceId, - }).map( - ([key, value]) => - html`` - )}`; - } - - private renderOtherElements(): TemplateResult { - return html`
    - ${this.renderSmvOptsContent()}${this.renderSmvContent()} -
    `; - } - - private renderSmvControlContent(): TemplateResult { - const [ - name, - desc, - multicast, - smvID, - smpMod, - smpRate, - nofASDU, - securityEnabled, - ] = [ - 'name', - 'desc', - 'multicast', - 'smvID', - 'smpMod', - 'smpRate', - 'nofASDU', - 'securityEnabled', - ].map(attr => this.element?.getAttribute(attr)); - - return html`
    - - - ${multicast === 'true' - ? html`` - : html``} - - ${['SmpPerPeriod', 'SmpPerSec', 'SecPerSmp'].map( - option => - html`${option}` - )} - - - ${['None', 'Signature', 'SignatureAndEncryption'].map( - type => html`${type}` - )} -
    `; - } - - render(): TemplateResult { - return html`

    -
    -
    SampledValueControl
    -
    ${identity(this.element)}
    -
    -

    -
    - ${this.renderSmvControlContent()}${this.renderOtherElements()} -
    `; - } - - static styles = css` - .parentcontent { - display: grid; - grid-gap: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(316px, auto)); - } - - .content { - border-left: thick solid var(--mdc-theme-on-primary); - } - - .content > * { - display: block; - margin: 4px 8px 16px; - } - - h2, - h3 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - margin: 4px 8px 16px; - padding-left: 0.3em; - } - - .headersubtitle { - font-size: 16px; - font-weight: 200; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - *[iconTrailing='search'] { - --mdc-shape-small: 28px; - } - - @media (max-width: 950px) { - .content { - border-left: 0px solid var(--mdc-theme-on-primary); - } - } - `; -} diff --git a/packages/plugins/src/editors/singlelinediagram/foundation.ts b/packages/plugins/src/editors/singlelinediagram/foundation.ts deleted file mode 100644 index 44c98fe33a..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/foundation.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { - getNameAttribute, - getPathNameAttribute, -} from '@openscd/open-scd/src/foundation.js'; - -/** - * A point is a position containing a x and a y within a SCL file. - */ -export interface Point { - x: number; - y: number; -} - -export const SCL_COORDINATES_NAMESPACE = - 'http://www.iec.ch/61850/2003/SCLcoordinates'; - -/** Scope factor: the ConnectivityNode allocation algorithm works better with a scale factor which is bigger than 1. */ -const COORDINATES_SCALE_FACTOR = 2; - -/** - * Get the coordinates of a XML element (x and y coordinates). - * @param element - The element to extract coordinates from. - * @returns A point containing the coordinates. - */ -export function getRelativeCoordinates(element: Element): Point { - const x = element.getAttributeNS(SCL_COORDINATES_NAMESPACE, 'x'); - const y = element.getAttributeNS(SCL_COORDINATES_NAMESPACE, 'y'); - - return { - x: x ? parseInt(x) * COORDINATES_SCALE_FACTOR : 0, - y: y ? parseInt(y) * COORDINATES_SCALE_FACTOR : 0, - }; -} - -/** - * Get the absolute (its own and all parents') coordinates of a SCL element (x and y coordinates) - * @param element - The element to extract coordinates from. - * @returns A point containing the coordinates. - */ -export function getAbsoluteCoordinates(element: Element): Point { - if (!element.parentElement || element.parentElement?.tagName === 'SCL') - return getRelativeCoordinates(element); - - const absParent = getAbsoluteCoordinates(element.parentElement); - const relElement = getRelativeCoordinates(element); - return { - x: absParent.x! + relElement.x!, - y: absParent.y! + relElement.y!, - }; -} - -/** - * Checking of an element is a BusBar or not. - * @param element - The element to check. - * @returns Is the element a BusBar or not. - */ -export function isBusBar(element: Element): boolean { - return ( - element.children.length === 1 && - element.children[0].tagName === 'ConnectivityNode' - ); -} - -/** - * Get all the connected terminals to a given element. - * @param element - The element to check. - * @returns All connected terminals. - */ -export function getConnectedTerminals(element: Element): Element[] { - const substationElement = element?.closest('Substation'); - if (!substationElement) return []; - - const path = getPathNameAttribute(element) ?? ''; - const [substationName, voltageLevelName, bayName] = path.split('/'); - - return Array.from(substationElement.getElementsByTagName('Terminal')).filter( - terminal => - terminal.getAttribute('connectivityNode') === path && - terminal.getAttribute('cNodeName') === getNameAttribute(element) && - (!terminal.hasAttribute('substationName') || - terminal.getAttribute('substationName') === substationName) && - (!terminal.hasAttribute('voltageLevelName') || - terminal.getAttribute('voltageLevelName') === voltageLevelName) && - (!terminal.hasAttribute('bayName') || - terminal.getAttribute('bayName') === bayName) - ); -} - -/** - * Calculate the SCL x and y coordinate of a Connectivity Node. - * The algorithm is as follow: - * - Get all elements that are connected to this Connectivity Node. - * - Extract the SCL x and y coordinates of these Connectivity Nodes and add them up. - * - Divide the final x and y numbers by the number of connected elements. This way, you get an so-called average. - * @param cNodeElement - The Connectivity Node to calculate the X and Y Coordinates for. - * @returns The calculated SCL x and y coordinates for this Connectivity Node. - */ -export function calculateConnectivityNodeCoordinates( - cNodeElement: Element -): Point { - // If element is not a Connectivity Node, return default {x: 0, y: 0} - if (cNodeElement.tagName != 'ConnectivityNode') return { x: 0, y: 0 }; - - const substationElement = cNodeElement.closest('Substation'); - const pathName = getPathNameAttribute(cNodeElement); - - let nrOfConnections = 0; - let nrOfXConnections = 0; - let totalX = 0; - let totalY = 0; - - Array.from( - substationElement!.querySelectorAll('ConductingEquipment, PowerTransformer') - ) - .filter( - equipment => - equipment.querySelector(`Terminal[connectivityNode="${pathName}"]`) != - null - ) - .forEach(equipment => { - nrOfConnections++; - - const { x, y } = getAbsoluteCoordinates(equipment); - - // Only if the Element is in the same bay, we will use that X-value to calculate the location - // of the Connectivity Node. This will cause the Connectivity Node to stay with the boundaries - // of the Bay and not causing al kind of overlays between bays. - if (equipment.parentElement === cNodeElement.parentElement) { - nrOfXConnections++; - totalX += x!; - } - totalY += y!; - }); - - if (nrOfConnections === 0) return { x: 0, y: 0 }; - if (nrOfConnections === 1) return { x: totalX + 1, y: totalY + 1 }; - - return { - x: Math.round(totalX / nrOfXConnections), - y: Math.round(totalY / nrOfConnections), - }; -} - -export function getCommonParentElement( - leftElement: Element, - rightElement: Element, - defaultParent: Element | null -): Element | null { - let leftParentElement = leftElement.parentElement; - while (leftParentElement) { - if (leftParentElement.contains(rightElement)) { - return leftParentElement; - } - leftParentElement = leftParentElement.parentElement; - } - return defaultParent; -} diff --git a/packages/plugins/src/editors/singlelinediagram/ortho-connector.ts b/packages/plugins/src/editors/singlelinediagram/ortho-connector.ts deleted file mode 100644 index 9c3f197072..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/ortho-connector.ts +++ /dev/null @@ -1,311 +0,0 @@ -interface Point { - x: number; - y: number; -} - -interface Adjacent { - point: Point; - edgeWeight: number; -} - -interface GraphNode { - point: Point; - adjacent: Adjacent[]; - dist: number; - path: Point[]; -} - -function distance(a: Point, b: Point): number { - return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2)); -} - -function isChangedDirection(a: GraphNode, b: GraphNode): boolean { - if (a.path.length === 0) return false; - - const commingX2 = a.point.x; - const commingX1 = a.path[a.path.length - 1].x; - const commingHorizontal = commingX2 - commingX1 ? false : true; - - const goingHorizontal = a.point.x - b.point.x ? false : true; - - return commingHorizontal !== goingHorizontal; -} - -function filterUnchangedDirection(path: Point[]): Point[] { - return path.filter((p, i, v) => { - if (i === 0 || i === v.length - 1) return true; - - const commingDirection = - v[i].x - v[i - 1].x !== 0 ? 'horizontal' : 'vertical'; - const goingDirection = - v[i + 1].x - v[i].x !== 0 ? 'horizontal' : 'vertical'; - - return commingDirection === goingDirection ? false : true; - }); -} - -function calculateMinimumDistance( - adjacent: GraphNode, - edgeWeigh: number, - parentNode: GraphNode -) { - const sourceDistance = parentNode.dist; - - const changingDirection = isChangedDirection(parentNode, adjacent); - const extraWeigh = changingDirection ? Math.pow(edgeWeigh + 1, 2) : 0; - - if (sourceDistance + edgeWeigh + extraWeigh < adjacent.dist) { - adjacent.dist = sourceDistance + edgeWeigh + extraWeigh; - const shortestPath: Point[] = [...parentNode.path]; - shortestPath.push(parentNode.point); - adjacent.path = shortestPath; - } -} - -function getLowestDistanceGraphNode( - unsettledNodes: Set -): GraphNode | null { - let lowestDistance = Number.MAX_SAFE_INTEGER; - let lowestDistanceNode: GraphNode | null = null; - - for (const node of unsettledNodes) - if (node.dist < lowestDistance) { - lowestDistance = node.dist; - lowestDistanceNode = node; - } - - return lowestDistanceNode; -} - -function dijkstra(graph: GraphNode[], start: GraphNode): Point[] { - start.dist = 0; - - const settledNodes: Set = new Set(); - const unsettledNodes: Set = new Set(); - - unsettledNodes.add(start); - - while (unsettledNodes.size != 0) { - const currentNode = getLowestDistanceGraphNode(unsettledNodes)!; - unsettledNodes.delete(currentNode); - - for (const adjacent of currentNode.adjacent) { - const adjacentNode = graph.find( - node => - node.point.x === adjacent.point.x && node.point.y === adjacent.point.y - ); - const edgeWeight = adjacent.edgeWeight; - if (adjacentNode && !settledNodes.has(adjacentNode)) { - calculateMinimumDistance(adjacentNode, edgeWeight, currentNode); - unsettledNodes.add(adjacentNode); - } - } - settledNodes.add(currentNode); - } - - return []; -} - -function findClosestGraphNode( - graph: GraphNode[], - point: Point -): GraphNode | undefined { - const distFromGraphNodes = graph.map( - node => Math.abs(point.x - node.point.x) + Math.abs(point.y - node.point.y) - ); - - const minDistance = Math.min(...distFromGraphNodes); - const index = distFromGraphNodes.indexOf(minDistance); - - return graph[index]; -} - -function addStartNode(graph: GraphNode[], start: Point): GraphNode | undefined { - const closestToStart = findClosestGraphNode(graph, start)?.point; - if (!closestToStart) return undefined; - - const startNode = { - point: start, - adjacent: [ - { point: closestToStart, edgeWeight: distance(start, closestToStart) }, - ], - dist: Number.MAX_SAFE_INTEGER, - path: [], - }; - graph.push(startNode); - - return startNode; -} - -function getPath(graph: GraphNode[], start: Point, end: Point): Point[] { - const startNode = addStartNode(graph, start); - const closestToEnd = findClosestGraphNode(graph, end); - - if (!startNode || !closestToEnd) return []; - - dijkstra(graph, startNode); - const shortestPath = closestToEnd.path.concat(closestToEnd.point); - - return filterUnchangedDirection(shortestPath).concat([end]); -} - -function findGraphNode( - graph: GraphNode[], - x: number, - y: number -): GraphNode | undefined { - return graph.find(node => node.point.x === x && node.point.y === y); -} - -function findAdjacent( - graph: GraphNode[], - currentNode: GraphNode, - gridSize: number, - type: string -): Adjacent | null { - let dX1: number; - let dY1: number; - - if (type === 'prevX') { - dX1 = currentNode.point.x - gridSize; - dY1 = currentNode.point.y; - } else if (type === 'prevY') { - dX1 = currentNode.point.x; - dY1 = currentNode.point.y - gridSize; - } else if (type === 'nextX') { - dX1 = currentNode.point.x + gridSize; - dY1 = currentNode.point.y; - } else { - dX1 = currentNode.point.x; - dY1 = currentNode.point.y + gridSize; - } - - if (findGraphNode(graph, dX1!, dY1!)) { - return { - point: findGraphNode(graph, dX1!, dY1!)!.point, - edgeWeight: gridSize, - }; - } - - return null; -} - -function createGraph(allocation: number[][], gridSize: number): GraphNode[] { - const graph: GraphNode[] = []; - for (let row = 0; row < allocation.length; row++) - for (let col = 0; col < allocation[row].length; col++) - if (allocation[row][col] === 0) - graph.push({ - point: { - x: col * gridSize + gridSize / 2, - y: row * gridSize + gridSize / 2, - }, - adjacent: [], - dist: Number.MAX_SAFE_INTEGER, - path: [], - }); - - for (const node of graph) { - const adjacents = ( - ['prevX', 'prevY', 'nextX', 'nextY'] - .map(type => findAdjacent(graph, node, gridSize, type)) - .filter(adjacent => adjacent) - ); - node.adjacent = adjacents; - } - - return graph; -} - -function emptyAllocation( - start: Point, - end: Point, - gridSize: number -): (0 | 1)[][] { - const maxX = start.x > end.x ? start.x : end.x; - const maxY = start.y > end.y ? start.y : end.y; - - const emptyGrid: (0 | 1)[][] = []; - for (let i = 0; i <= Math.ceil(maxY / gridSize) + 1; i++) { - emptyGrid[i] = []; - for (let j = 0; j <= Math.ceil(maxX / gridSize) + 1; j++) { - emptyGrid[i][j] = 0; - } - } - - emptyGrid[Math.floor(start.y / gridSize)][Math.floor(start.x / gridSize)] = 1; - emptyGrid[Math.floor(end.y / gridSize)][Math.floor(end.x / gridSize)] = 1; - - return emptyGrid; -} - -//FIXME: This is a dirty trick to improve performance of the algorithm -function trimStartEnd(start: Point, end: Point, gridSize: number): Point[] { - //FIXME: Dirty hack to speed up the algorithm - const minCoordX = Math.min( - Math.floor(start.x / gridSize), - Math.floor(end.x / gridSize) - ); - const minCoordY = Math.min( - Math.floor(start.y / gridSize), - Math.floor(end.y / gridSize) - ); - - const dCoordX = minCoordX > 1 ? minCoordX - 1 : 0; - const dCoordY = minCoordY > 1 ? minCoordY - 1 : 0; - - const deltaX = dCoordX * gridSize; - const deltaY = dCoordY * gridSize; - - return [ - { x: start.x - deltaX, y: start.y - deltaY }, - { x: end.x - deltaX, y: end.y - deltaY }, - ]; -} - -function fullPath( - path: Point[], - start: Point, - end: Point, - trimmedStart: Point, - trimmedEnd: Point -): Point[] { - if (start === trimmedStart && end === trimmedEnd) return path; - - const deltaX = start.x - trimmedStart.x; - const deltaY = start.y - trimmedStart.y; - - return path.map(point => { - return { x: point.x + deltaX, y: point.y + deltaY }; - }); -} - -/** Finds the shortest orthogonal path between start and end based on grid and dijkstra path finding algorithm - * @param start - the position in px of the start point - * @param end - the position in px of the end point - * @param gridSize - grid size of the grid to rout in the orthogonal path - * @param gridAllocation - optional [][] matrix to define allocated grid cells - * @returns - Array of positions in px building the orthogonal path - */ -export function getOrthogonalPath( - start: Point, - end: Point, - gridSize: number, - gridAllocation?: (0 | 1)[][] -): Point[] { - if (start.x === end.x && start.y === end.y) return []; - - let trimmedStart = start; - let trimmedEnd = end; - - if (!gridAllocation) { - [trimmedStart, trimmedEnd] = trimStartEnd(start, end, gridSize); - gridAllocation = emptyAllocation(trimmedStart, trimmedEnd, gridSize); - } - - const graph: GraphNode[] = createGraph(gridAllocation!, gridSize); - - const shortesPath = getPath(graph, trimmedStart, trimmedEnd); - - return fullPath(shortesPath, start, end, trimmedStart, trimmedEnd); -} diff --git a/packages/plugins/src/editors/singlelinediagram/sld-drawing.ts b/packages/plugins/src/editors/singlelinediagram/sld-drawing.ts deleted file mode 100644 index 14bbd6127b..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/sld-drawing.ts +++ /dev/null @@ -1,678 +0,0 @@ -import { - getDescriptionAttribute, - getNameAttribute, - identity, -} from '@openscd/open-scd/src/foundation.js'; -import { getIcon } from '../substation/foundation.js'; -import { - connectivityNodeIcon, - editIcon, - powerTransformerTwoWindingIcon, -} from '@openscd/open-scd/src/icons/icons.js'; - -import { - getRelativeCoordinates, - Point, - getAbsoluteCoordinates, - calculateConnectivityNodeCoordinates, -} from './foundation.js'; -import { getOrthogonalPath } from './ortho-connector.js'; - -/** Default 'grid size' of our SVG */ -export const SVG_GRID_SIZE = 64; - -/** Size of SLC element ConductingEquipment or PowerTransformer */ -export const EQUIPMENT_SIZE = 50; - -/** The size of SLC element ConnectivityNode */ -export const CNODE_SIZE = 25; - -/** Offset of a terminal next to its parent element */ -const TERMINAL_OFFSET = 6; - -type Direction = 'top' | 'right' | 'bottom' | 'left'; -/** Start and end direction of the route */ - -export interface PointDirections { - startDirection: Direction; - endDirection: Direction; -} - -/** - * Get the full position of an element (multiplied with an offset for the SVG). - * It's just a matter of adding all the position up of the element including it's parent(s). - * @param element - The SCL element to get the position for. - * @returns A point containing the full x/y position. - */ -export function getAbsolutePosition(element: Element): Point { - const absoluteCoordinates = getAbsoluteCoordinates(element); - return { - x: - absoluteCoordinates.x! * SVG_GRID_SIZE + - (SVG_GRID_SIZE - EQUIPMENT_SIZE) / 2, - y: - absoluteCoordinates.y! * SVG_GRID_SIZE + - (SVG_GRID_SIZE - EQUIPMENT_SIZE) / 2, - }; -} - -/** - * Get the full position of an bus bar (multiplied with an offset for the SVG). - * @param busbar - The SCL element Bay to get the position for. - * @returns A point containing the full x/y position in px. - */ -export function getAbsolutePositionBusBar(busbar: Element): Point { - const absoluteCoordinates = getAbsoluteCoordinates(busbar); - return { - x: absoluteCoordinates.x! * SVG_GRID_SIZE, - y: absoluteCoordinates.y! * SVG_GRID_SIZE, - }; -} - -/** - * Get the full position of an ConnectivityNode SCL element (multiplied with an offset for the SVG). - * @param connectivityNode - The SCL element ConnectivityNode to get the position for. - * @returns A point containing the full x/y position in px. - */ -export function getAbsolutePositionConnectivityNode( - connectivityNode: Element -): Point { - const absoluteCoordinates = - calculateConnectivityNodeCoordinates(connectivityNode); - return { - x: - absoluteCoordinates.x! * SVG_GRID_SIZE + (SVG_GRID_SIZE - CNODE_SIZE) / 2, - y: - absoluteCoordinates.y! * SVG_GRID_SIZE + (SVG_GRID_SIZE - CNODE_SIZE) / 2, - }; -} - -/** - * Calculate the absolute offset of a terminal next to an element. - * @param parentElementPosition - The position of the parent element of the terminal. - * @param elementOffset - The offset of the parent element. - * @param terminalSide - The side of the parent element where the terminal should be placed. - * @param customTerminalOffset - An optional parameter containing the offset of the terminal next to the parent element. - * This may vary, for example for Connectivity Nodes. - * - * @returns The absolute position of the terminal. - */ -function absoluteOffsetTerminal( - parentElementPosition: Point, - elementOffset: number, - terminalSide: Direction, - customTerminalOffset?: number -): Point { - const terminalOffset = customTerminalOffset ?? TERMINAL_OFFSET; - - switch (terminalSide) { - case 'top': { - const x = parentElementPosition.x; - const y = parentElementPosition.y; - return { - x: x! + elementOffset / 2, - y: y! - terminalOffset, - }; - } - case 'bottom': { - const x = parentElementPosition.x; - const y = parentElementPosition.y; - return { - x: x! + elementOffset / 2, - y: y! + (elementOffset + terminalOffset), - }; - } - case 'left': { - const x = parentElementPosition.x; - const y = parentElementPosition.y; - return { - x: x! - terminalOffset, - y: y! + elementOffset / 2, - }; - } - case 'right': { - const x = parentElementPosition.x; - const y = parentElementPosition.y; - return { - x: x! + (elementOffset + terminalOffset), - y: y! + elementOffset / 2, - }; - } - default: { - return parentElementPosition; - } - } -} - -/** - * Get the absolute position in py for a equipments Terminal (based on the TERMINAL_OFFSET). - * @param equipment - The SCL elements ConductingEquipment or PowerTransformer. - * @param direction - On which side does the terminal needs to be placed relative to the given point. - */ -export function getAbsolutePositionTerminal( - equipment: Element, - direction: Direction -): Point { - const parentElementPosition = getAbsolutePosition(equipment); - - return absoluteOffsetTerminal( - parentElementPosition, - EQUIPMENT_SIZE, - direction - ); -} - -/** - * Get the absolute position in px for a SLC element ConnectivityNode drawing start/end (based on the TERMINAL_OFFSET). - * @param cNode - The SCL element ConnectivityNode - * @param direction - The direction of the connector from/to the ConnectivityNode - */ -export function getConnectivityNodesDrawingPosition( - cNode: Element, - direction: Direction -): Point { - const parentElementPosition = getAbsolutePositionConnectivityNode(cNode); - - // Using a custom terminal offset for Connectivity Nodes, so the routes are nicely connected to the Connectivity Nodes. - const customTerminalOffset = -(CNODE_SIZE / 3); - return absoluteOffsetTerminal( - parentElementPosition, - CNODE_SIZE, - direction, - customTerminalOffset - ); -} - -/** - * Create a element based on a single XML element. - * @param element - The element. - * @returns The element. - */ -function createGroupElement(element: Element): SVGGraphicsElement { - const finalElement = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'g' - ); - finalElement.setAttribute( - 'id', - typeof identity(element) === 'string' - ? identity(element) - : 'unidentifiable' - ); - finalElement.setAttribute('type', element.tagName); - - const description = getDescriptionAttribute(element); - if (description) finalElement.setAttribute('desc', description); - - // Setting the X and Y coordinates of this element. - // It's not actually used, it's more informative. - const coordinates = getRelativeCoordinates(element); - finalElement.setAttribute('sxy:x', `${coordinates.x}`); - finalElement.setAttribute('sxy:y', `${coordinates.y}`); - - return finalElement; -} - -/** - * Create a Substation element. - * @param substation - The Substation from the SCL document to use. - * @returns A Substation element. - */ -export function createSubstationElement(substation: Element): SVGElement { - return createGroupElement(substation); -} - -/** - * Create a Voltage Level element. - * @param voltageLevel - The Voltage Level from the SCL document to use. - * @returns A Voltage Level element. - */ -export function createVoltageLevelElement(voltageLevel: Element): SVGElement { - return createGroupElement(voltageLevel); -} - -/** - * Create a Bay element. - * @param bayElement - The Bay from the SCL document to use. - * @returns A Bay element. - */ -export function createBayElement(bayElement: Element): SVGGraphicsElement { - return createGroupElement(bayElement); -} - -/** - * Add a Text Element to the top of the Bay - * - * @param rootGroup - The Root group containing all groups. - * @param bayElement - The Bay from the SCL document to use. - * @param clickAction - The action to execute when the Name of the Bay is being clicked. - */ -export function addLabelToBay( - rootGroup: SVGElement, - bayElement: Element, - clickAction?: (event: Event) => void -): void { - rootGroup - .querySelectorAll(`g[id="${identity(bayElement)}"]`) - .forEach(bayGroup => { - const labelGroup = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'g' - ); - labelGroup.setAttribute('type', 'BayLabel'); - if (clickAction) labelGroup.addEventListener('click', clickAction); - bayGroup.prepend(labelGroup); - - const bayBox = (bayGroup).getBBox(); - const text = createTextElement( - bayElement.getAttribute('name') || '', - { x: bayBox.x, y: bayBox.y - 20 }, - 'medium' - ); - labelGroup.append(text); - - const textBox = text.getBBox(); - const parsedIcon = new DOMParser().parseFromString( - editIcon.strings[0], - 'application/xml' - ); - parsedIcon.querySelectorAll('circle,path,line').forEach(icon => { - icon.setAttribute( - 'transform', - `translate(${textBox.x + textBox.width + 5},${textBox.y}) scale(0.75)` - ); - labelGroup.append(icon); - }); - }); -} - -/** - * Create a basic caption. - * @param textContent - The content of the caption. - * @param coordinates - The x and y position in px to locate in drawing pane. - * @param textSize - The size of the caption - * @returns The text SVG element. - */ -export function createTextElement( - textContent: string, - coordinates: Point, - textSize: string -): SVGGraphicsElement { - const finalElement = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'text' - ); - - finalElement.textContent = textContent; - finalElement.setAttribute( - 'style', - `font-family: Roboto, sans-serif; font-weight: 300; font-size: ${textSize}` - ); - - finalElement.setAttribute('x', `${coordinates.x}`); - finalElement.setAttribute('y', `${coordinates.y}`); - - return finalElement; -} - -/** - * Create a Terminal element. - * @param terminal - The SCL element Terminal to draw - * @param sideToDraw - The side of the element the terminal must be drawn on. - * @param clickAction - The action to execute when the terminal is being clicked. - * @returns The terminal SVG element. - */ -export function createTerminalElement( - terminal: Element, - sideToDraw: Direction, - clickAction?: (event: Event) => void -): SVGElement { - const groupElement = createGroupElement(terminal); - - const terminalIdentity = - typeof identity(terminal) === 'string' - ? identity(terminal) - : 'unidentifiable'; - - const parentEquipment = terminal.closest( - 'ConductingEquipment, PowerTransformer' - ); - const terminalPosition = getAbsolutePositionTerminal( - parentEquipment!, - sideToDraw - ); - - const icon = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); - icon.setAttribute('id', `${terminalIdentity}`); - icon.setAttribute('cx', `${terminalPosition.x}`); - icon.setAttribute('cy', `${terminalPosition.y}`); - icon.setAttribute('r', '2'); - groupElement.appendChild(icon); - - if (clickAction) groupElement.addEventListener('click', clickAction); - - return groupElement; -} - -/** - * Create a bus bar element. - * @param busbarElement - The Bus Bar SCL Element. - * @param busbarLength - The length of the bus bar depending on the x coordinate of the most far out right equipment () - * @returns The Bus Bar SVG element. - */ -export function createBusBarElement( - busbarElement: Element, - busbarLength: number -): SVGGraphicsElement { - const groupElement = createGroupElement(busbarElement); - // Overwrite the type to make a distinction between Bays and Busbars. - groupElement.setAttribute('type', 'Busbar'); - - const absolutePosition = getAbsolutePositionBusBar(busbarElement); - - // TODO: Add this to the icons.ts file. - const icon = document.createElementNS('http://www.w3.org/2000/svg', 'line'); - icon.setAttribute('name', getNameAttribute(busbarElement)!); - icon.setAttribute('stroke-width', '4'); - icon.setAttribute('stroke', 'currentColor'); - - icon.setAttribute('x1', `${absolutePosition.x}`); - icon.setAttribute('y1', `${absolutePosition.y}`); - icon.setAttribute('x2', `${busbarLength}`); - icon.setAttribute('y2', `${absolutePosition.y}`); - - groupElement.appendChild(icon); - - return groupElement; -} - -/** - * Add a Text Element to the top of the Bay - * - * @param rootGroup - The Root group containing all groups. - * @param busbarElement - The BusBar from the SCL document to use. - * @param clickAction - The action to execute when the Name of the BusBar is being clicked. - */ -export function addLabelToBusBar( - rootGroup: SVGElement, - busbarElement: Element, - clickAction?: (event: Event) => void -): void { - rootGroup - .querySelectorAll(`g[id="${identity(busbarElement)}"]`) - .forEach(busbarGroup => { - const labelGroup = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'g' - ); - labelGroup.setAttribute('type', 'BusbarLabel'); - if (clickAction) labelGroup.addEventListener('click', clickAction); - busbarGroup.prepend(labelGroup); - - const busbarBox = (busbarGroup).getBBox(); - const text = createTextElement( - busbarElement.getAttribute('name') || '', - { x: busbarBox.x, y: busbarBox.y - 20 }, - 'medium' - ); - labelGroup.append(text); - - const textBox = text.getBBox(); - const parsedIcon = new DOMParser().parseFromString( - editIcon.strings[0], - 'application/xml' - ); - parsedIcon.querySelectorAll('circle,path,line').forEach(icon => { - icon.setAttribute( - 'transform', - `translate(${textBox.x + textBox.width + 5},${textBox.y}) scale(0.75)` - ); - labelGroup.append(icon); - }); - }); -} - -/** - * Create a Conducting Equipment element. - * @param equipmentElement - The SCL element ConductingEquipment - * @param clickAction - The action to execute when the Conducting Equipment is being clicked. - * @returns The Conducting Equipment SVG element. - */ -export function createConductingEquipmentElement( - equipmentElement: Element, - clickAction?: (event: Event) => void -): SVGElement { - const groupElement = createGroupElement(equipmentElement); - - const absolutePosition = getAbsolutePosition(equipmentElement); - const parsedIcon = new DOMParser().parseFromString( - getIcon(equipmentElement).strings[0], - 'application/xml' - ); - parsedIcon.querySelectorAll('circle,path,line').forEach(icon => { - icon.setAttribute( - 'transform', - `translate(${absolutePosition.x},${absolutePosition.y}) scale(${ - EQUIPMENT_SIZE / 25 - })` - ); - groupElement.appendChild(icon); - }); - - const text = createTextElement( - getNameAttribute(equipmentElement)!, - { x: absolutePosition.x! - 15, y: absolutePosition.y! + 30 }, - 'x-small' - ); - groupElement.appendChild(text); - - if (clickAction) groupElement.addEventListener('click', clickAction); - - return groupElement; -} - -/** - * Create a PowerTransformer element. - * @param powerTransformerElement - The SCL element PowerTransformer - * @param clickAction - The action to execute when the Power Transformer is being clicked. - * @returns The Power Transformer SVG element. - */ -export function createPowerTransformerElement( - powerTransformerElement: Element, - clickAction?: (event: Event) => void -): SVGElement { - const groupElement = createGroupElement(powerTransformerElement); - - const absolutePosition = getAbsolutePosition(powerTransformerElement); - const parsedIcon = new DOMParser().parseFromString( - powerTransformerTwoWindingIcon.strings[0], - 'application/xml' - ); - parsedIcon.querySelectorAll('circle,path,line').forEach(icon => { - icon.setAttribute( - 'transform', - `translate(${absolutePosition.x},${absolutePosition.y}) scale(${ - EQUIPMENT_SIZE / 25 - })` - ); - groupElement.appendChild(icon); - }); - - const text = createTextElement( - getNameAttribute(powerTransformerElement)!, - { x: absolutePosition.x! - 15, y: absolutePosition.y! + 30 }, - 'x-small' - ); - groupElement.appendChild(text); - - if (clickAction) groupElement.addEventListener('click', clickAction); - - return groupElement; -} - -/** - * Create a Connectivity Node element. - * @param cNodeElement - The SCL element ConnectivityNode - * @param clickAction - The action to execute when the Terminal is being clicked. - * @returns The Connectivity Node SVG element. - */ -export function createConnectivityNodeElement( - cNodeElement: Element, - clickAction?: (event: Event) => void -): SVGElement { - const groupElement = createGroupElement(cNodeElement); - - const parsedIcon = new DOMParser().parseFromString( - connectivityNodeIcon.strings[0], - 'application/xml' - ); - - const absolutePosition = getAbsolutePositionConnectivityNode(cNodeElement); - parsedIcon.querySelectorAll('circle').forEach(icon => { - icon.setAttribute( - 'transform', - `translate(${absolutePosition.x},${absolutePosition.y})` - ); - groupElement.appendChild(icon); - }); - - if (clickAction) groupElement.addEventListener('click', clickAction); - - return groupElement; -} - -/** - * Draw a route from ConnectivityNode to equipments Terminal (ConductingEquipment or PowerTransformer) - * @param cNodesTerminalPosition - The start position in px of the SCL element ConnectivityNode. - * @param equipmentsTerminalPosition - The end position in px of the SCL element ConductingEquipment or PowerTransformer. - * @param svgElementToDrawOn - The SVG Element to draw the route on. - */ -export function drawCNodeConnections( - cNodesTerminalPosition: Point, - equipmentsTerminalPosition: Point, - svgElementToDrawOn: SVGElement -): void { - const path = getOrthogonalPath( - equipmentsTerminalPosition, - cNodesTerminalPosition, - SVG_GRID_SIZE - ); - - const line = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - let d = ''; - path.forEach(({ x, y }, index) => { - if (index === 0) { - d = d + ` M ${x} ${y}`; - } else { - d = d + ` L ${x} ${y}`; - } - }); - - line.setAttribute('d', d); - line.setAttribute('fill', 'transparent'); - line.setAttribute('stroke', 'currentColor'); - line.setAttribute('stroke-width', '1'); - - // Inserting elements like this works kind of like z-index (not supported in SVG yet), - // these elements are placed behind all other elements. - // By doing it like this, all other elements are hoverable for example. - svgElementToDrawOn.insertAdjacentElement('afterbegin', line); -} - -/** - * Draw a route from the bus bar to elements terminal position. - * @param busbarsTerminalPosition - The start position in px the bus bar. - * @param equipmentsTerminalPosition - The end position in px of the SCL element ConductingEquipment or PowerTransformer. - * @param svgElementToDrawOn - The SVG Element to draw the route on. - */ -export function drawBusBarRoute( - busbarsTerminalPosition: Point, - equipmentsTerminalPosition: Point, - svgElementToDrawOn: SVGElement -): void { - const path = [busbarsTerminalPosition].concat([equipmentsTerminalPosition]); - - const line = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - let d = ''; - path.forEach(({ x, y }, index) => { - if (index === 0) { - d = d + ` M ${x} ${y}`; - } else { - d = d + ` L ${x} ${y}`; - } - }); - - line.setAttribute('d', d); - line.setAttribute('fill', 'transparent'); - line.setAttribute('stroke', 'currentColor'); - line.setAttribute('stroke-width', '1.5'); - - svgElementToDrawOn.appendChild(line); -} - -/** - * Small simple algorithm deciding on which direction the route should be drawn - * for a connection between elements Terminal and ConnectivityNode - * @param equipment - The SCL element ConductingEquipment or PowerTransformer the route starts from. - * @param cNode - The SLC element ConnectivityNode the route ends with. - * @returns The sides of both points . - */ -export function getDirections( - equipment: Element, - cNode: Element -): PointDirections { - const pointA = getAbsoluteCoordinates(equipment); - const pointB = calculateConnectivityNodeCoordinates(cNode); - - if (pointA.y < pointB.y && pointA.x < pointB.x) - return { startDirection: 'bottom', endDirection: 'left' }; - - if (pointA.y < pointB.y && pointA.x > pointB.x) - return { startDirection: 'bottom', endDirection: 'right' }; - - if (pointA.y < pointB.y && pointA.x === pointB.x) - return { startDirection: 'bottom', endDirection: 'top' }; - - if (pointA.y > pointB.y && pointA.x < pointB.x) - return { startDirection: 'top', endDirection: 'left' }; - - if (pointA.y > pointB.y && pointA.x > pointB.x) - return { startDirection: 'top', endDirection: 'right' }; - - if (pointA.y > pointB.y && pointA.x === pointB.x) - return { startDirection: 'top', endDirection: 'bottom' }; - - if (pointA.y === pointB.y && pointA.x > pointB.x) - return { startDirection: 'left', endDirection: 'right' }; - - if (pointA.y === pointB.y && pointA.x < pointB.x) - return { startDirection: 'right', endDirection: 'left' }; - - return { startDirection: 'bottom', endDirection: 'top' }; -} - -/** - * Get the name of the parent of given child element. - * @param childElement - The child element. - * @returns The name. - */ -export function getParentElementName( - childElement: Element -): string | undefined { - const parentElement = childElement.parentElement; - return getNameAttribute(parentElement); -} - -/* Calculate length of the busbar that is depending on the most far right equipment - * @param root - Either the whole SCL file or the voltage level where the bus bar resides - * @returns - the length of the bus bar - */ -export function getBusBarLength(root: Element): number { - return ( - Math.max( - ...Array.from( - root.querySelectorAll('ConductingEquipment, PowerTransformer') - ).map(equipment => getAbsolutePosition(equipment).x!) - ) + SVG_GRID_SIZE - ); -} diff --git a/packages/plugins/src/editors/singlelinediagram/wizards/bay.ts b/packages/plugins/src/editors/singlelinediagram/wizards/bay.ts deleted file mode 100644 index 08f5849309..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/wizards/bay.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import { Wizard } from '@openscd/open-scd/src/foundation.js'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { renderBayWizard } from '../../../wizards/bay.js'; -import { - getDescAttribute, - getNameAttribute, - getXCoordinateAttribute, - getYCoordinateAttribute, - updateNamingAndCoordinatesAction, - renderXYCoordinateFields, -} from './foundation.js'; - -function render( - name: string | null, - desc: string | null, - xCoordinate: string | null, - yCoordinate: string | null -): TemplateResult[] { - return renderBayWizard(name, desc).concat( - renderXYCoordinateFields(xCoordinate, yCoordinate) - ); -} - -export function editBayWizard(element: Element): Wizard { - return [ - { - title: get('bay.wizard.title.edit'), - element, - primary: { - icon: 'edit', - label: get('save'), - action: updateNamingAndCoordinatesAction(element), - }, - content: render( - getNameAttribute(element), - getDescAttribute(element), - getXCoordinateAttribute(element), - getYCoordinateAttribute(element) - ), - }, - ]; -} diff --git a/packages/plugins/src/editors/singlelinediagram/wizards/conductingequipment.ts b/packages/plugins/src/editors/singlelinediagram/wizards/conductingequipment.ts deleted file mode 100644 index 0fdb2bc8ed..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/wizards/conductingequipment.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { Wizard } from '@openscd/open-scd/src/foundation.js'; -import { - getDescAttribute, - getNameAttribute, - getXCoordinateAttribute, - getYCoordinateAttribute, - updateNamingAndCoordinatesAction, - renderXYCoordinateFields, -} from './foundation.js'; -import { - renderConductingEquipmentWizard, - reservedNamesConductingEquipment, - typeName, -} from '../../../wizards/conductingequipment.js'; - -export function render( - name: string | null, - desc: string | null, - xCoordinate: string | null, - yCoordinate: string | null, - option: 'edit' | 'create', - type: string, - reservedNames: string[] -): TemplateResult[] { - return renderConductingEquipmentWizard( - name, - desc, - option, - type, - reservedNames - ).concat(renderXYCoordinateFields(xCoordinate, yCoordinate)); -} - -export function editConductingEquipmentWizard(element: Element): Wizard { - const reservedNames = reservedNamesConductingEquipment( - element.parentNode!, - element.getAttribute('name') - ); - - return [ - { - title: get('conductingequipment.wizard.title.edit'), - element, - primary: { - icon: 'edit', - label: get('save'), - action: updateNamingAndCoordinatesAction(element), - }, - content: render( - getNameAttribute(element), - getDescAttribute(element), - getXCoordinateAttribute(element), - getYCoordinateAttribute(element), - 'edit', - typeName(element), - reservedNames - ), - }, - ]; -} diff --git a/packages/plugins/src/editors/singlelinediagram/wizards/foundation.ts b/packages/plugins/src/editors/singlelinediagram/wizards/foundation.ts deleted file mode 100644 index b179476f82..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/wizards/foundation.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { html, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import { - getValue, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; - -import { - cloneElement -} from '@openscd/xml'; - -import { EditorAction } from '@openscd/core/foundation/deprecated/editor.js'; -import { SCL_COORDINATES_NAMESPACE } from '../foundation.js'; - -export function getNameAttribute(element: Element): string | null { - return element.getAttribute('name'); -} - -export function getDescAttribute(element: Element): string | null { - return element.getAttribute('desc'); -} - -export function getXCoordinateAttribute(element: Element): string | null { - return element.getAttributeNS(SCL_COORDINATES_NAMESPACE, 'x'); -} - -export function getYCoordinateAttribute(element: Element): string | null { - return element.getAttributeNS(SCL_COORDINATES_NAMESPACE, 'y'); -} - -export function getFixedCoordinateValue(value: string | null): string | null { - if (value === null) { - return value; - } - - let convertedValue = Number(value); - if (isNaN(convertedValue) || convertedValue < 0) { - convertedValue = 0; - } - - return convertedValue.toString(); -} - -function updateXYAttribute( - element: Element, - attributeName: string, - value: string | null -): void { - if (value === null) { - element.removeAttributeNS(SCL_COORDINATES_NAMESPACE, attributeName); - } else { - element.setAttributeNS(SCL_COORDINATES_NAMESPACE, attributeName, value); - } -} - -export function updateNamingAndCoordinatesAction( - element: Element -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const name = getValue(inputs.find(i => i.label === 'name')!)!; - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const xCoordinate = getValue(inputs.find(i => i.label === 'xCoordinate')!); - const yCoordinate = getValue(inputs.find(i => i.label === 'yCoordinate')!); - - if ( - name === getNameAttribute(element) && - desc === getDescAttribute(element) && - xCoordinate === getXCoordinateAttribute(element) && - yCoordinate === getYCoordinateAttribute(element) - ) { - return []; - } - - const newElement = cloneElement(element, { name, desc }); - updateXYAttribute(newElement, 'x', getFixedCoordinateValue(xCoordinate)); - updateXYAttribute(newElement, 'y', getFixedCoordinateValue(yCoordinate)); - - return [{ old: { element }, new: { element: newElement } }]; - }; -} - -export function renderXYCoordinateFields( - xCoordinate: string | null, - yCoordinate: string | null -): TemplateResult[] { - return [ - html``, - html``, - ]; -} diff --git a/packages/plugins/src/editors/singlelinediagram/wizards/powertransformer.ts b/packages/plugins/src/editors/singlelinediagram/wizards/powertransformer.ts deleted file mode 100644 index 45cdcf3d36..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/wizards/powertransformer.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import { Wizard } from '@openscd/open-scd/src/foundation.js'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { - reservedNamesPowerTransformer, - renderPowerTransformerWizard, -} from '../../../wizards/powertransformer.js'; -import { - getDescAttribute, - getNameAttribute, - getXCoordinateAttribute, - getYCoordinateAttribute, - updateNamingAndCoordinatesAction, - renderXYCoordinateFields, -} from './foundation.js'; - -function render( - name: string | null, - desc: string | null, - type: string | null, - xCoordinate: string | null, - yCoordinate: string | null, - reservedNames: string[] -): TemplateResult[] { - return renderPowerTransformerWizard(name, desc, type, reservedNames).concat( - renderXYCoordinateFields(xCoordinate, yCoordinate) - ); -} - -export function editPowerTransformerWizard(element: Element): Wizard { - return [ - { - title: get('powertransformer.wizard.title.edit'), - element, - primary: { - icon: 'edit', - label: get('save'), - action: updateNamingAndCoordinatesAction(element), - }, - content: render( - getNameAttribute(element), - getDescAttribute(element), - element.getAttribute('type'), - getXCoordinateAttribute(element), - getYCoordinateAttribute(element), - reservedNamesPowerTransformer(element) - ), - }, - ]; -} diff --git a/packages/plugins/src/editors/singlelinediagram/wizards/wizard-library.ts b/packages/plugins/src/editors/singlelinediagram/wizards/wizard-library.ts deleted file mode 100644 index 5bbdf25bf1..0000000000 --- a/packages/plugins/src/editors/singlelinediagram/wizards/wizard-library.ts +++ /dev/null @@ -1,516 +0,0 @@ -import { SCLTag, Wizard } from '@openscd/open-scd/src/foundation.js'; -import { emptyWizard } from '../../../wizards/wizard-library.js'; - -import { editConnectivityNodeWizard } from '../../../wizards/connectivitynode.js'; -import { editTerminalWizard } from '../../../wizards/terminal.js'; - -import { editBayWizard } from './bay.js'; -import { editConductingEquipmentWizard } from './conductingequipment.js'; -import { editPowerTransformerWizard } from './powertransformer.js'; - -type SclElementWizard = (element: Element) => Wizard | undefined; - -export const wizards: Record< - SCLTag, - { - edit: SclElementWizard; - create: SclElementWizard; - } -> = { - AccessControl: { - edit: emptyWizard, - create: emptyWizard, - }, - AccessPoint: { - edit: emptyWizard, - create: emptyWizard, - }, - Address: { - edit: emptyWizard, - create: emptyWizard, - }, - Association: { - edit: emptyWizard, - create: emptyWizard, - }, - Authentication: { - edit: emptyWizard, - create: emptyWizard, - }, - BDA: { - edit: emptyWizard, - create: emptyWizard, - }, - BitRate: { - edit: emptyWizard, - create: emptyWizard, - }, - Bay: { - edit: editBayWizard, - create: emptyWizard, - }, - ClientLN: { - edit: emptyWizard, - create: emptyWizard, - }, - ClientServices: { - edit: emptyWizard, - create: emptyWizard, - }, - CommProt: { - edit: emptyWizard, - create: emptyWizard, - }, - Communication: { - edit: emptyWizard, - create: emptyWizard, - }, - ConductingEquipment: { - edit: editConductingEquipmentWizard, - create: emptyWizard, - }, - ConfDataSet: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfLdName: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfLNs: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfLogControl: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfReportControl: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfSG: { - edit: emptyWizard, - create: emptyWizard, - }, - ConfSigRef: { - edit: emptyWizard, - create: emptyWizard, - }, - ConnectedAP: { - edit: emptyWizard, - create: emptyWizard, - }, - ConnectivityNode: { - edit: editConnectivityNodeWizard, - create: emptyWizard, - }, - DA: { - edit: emptyWizard, - create: emptyWizard, - }, - DAI: { - edit: emptyWizard, - create: emptyWizard, - }, - DAType: { - edit: emptyWizard, - create: emptyWizard, - }, - DO: { - edit: emptyWizard, - create: emptyWizard, - }, - DOI: { - edit: emptyWizard, - create: emptyWizard, - }, - DOType: { - edit: emptyWizard, - create: emptyWizard, - }, - DataObjectDirectory: { - edit: emptyWizard, - create: emptyWizard, - }, - DataSet: { - edit: emptyWizard, - create: emptyWizard, - }, - DataSetDirectory: { - edit: emptyWizard, - create: emptyWizard, - }, - DataTypeTemplates: { - edit: emptyWizard, - create: emptyWizard, - }, - DynAssociation: { - edit: emptyWizard, - create: emptyWizard, - }, - DynDataSet: { - edit: emptyWizard, - create: emptyWizard, - }, - EnumType: { - edit: emptyWizard, - create: emptyWizard, - }, - EnumVal: { - edit: emptyWizard, - create: emptyWizard, - }, - EqFunction: { - edit: emptyWizard, - create: emptyWizard, - }, - EqSubFunction: { - edit: emptyWizard, - create: emptyWizard, - }, - ExtRef: { - edit: emptyWizard, - create: emptyWizard, - }, - FCDA: { - edit: emptyWizard, - create: emptyWizard, - }, - FileHandling: { - edit: emptyWizard, - create: emptyWizard, - }, - Function: { - edit: emptyWizard, - create: emptyWizard, - }, - GeneralEquipment: { - edit: emptyWizard, - create: emptyWizard, - }, - GetCBValues: { - edit: emptyWizard, - create: emptyWizard, - }, - GetDataObjectDefinition: { - edit: emptyWizard, - create: emptyWizard, - }, - GetDataSetValue: { - edit: emptyWizard, - create: emptyWizard, - }, - GetDirectory: { - edit: emptyWizard, - create: emptyWizard, - }, - GOOSE: { - edit: emptyWizard, - create: emptyWizard, - }, - GOOSESecurity: { - edit: emptyWizard, - create: emptyWizard, - }, - GSE: { - edit: emptyWizard, - create: emptyWizard, - }, - GSEDir: { - edit: emptyWizard, - create: emptyWizard, - }, - GSEControl: { - edit: emptyWizard, - create: emptyWizard, - }, - GSESettings: { - edit: emptyWizard, - create: emptyWizard, - }, - GSSE: { - edit: emptyWizard, - create: emptyWizard, - }, - Header: { - edit: emptyWizard, - create: emptyWizard, - }, - History: { - edit: emptyWizard, - create: emptyWizard, - }, - Hitem: { - edit: emptyWizard, - create: emptyWizard, - }, - IED: { - edit: emptyWizard, - create: emptyWizard, - }, - IEDName: { - edit: emptyWizard, - create: emptyWizard, - }, - Inputs: { - edit: emptyWizard, - create: emptyWizard, - }, - IssuerName: { - edit: emptyWizard, - create: emptyWizard, - }, - KDC: { - edit: emptyWizard, - create: emptyWizard, - }, - LDevice: { - edit: emptyWizard, - create: emptyWizard, - }, - LN: { - edit: emptyWizard, - create: emptyWizard, - }, - LN0: { - edit: emptyWizard, - create: emptyWizard, - }, - LNode: { - edit: emptyWizard, - create: emptyWizard, - }, - LNodeType: { - edit: emptyWizard, - create: emptyWizard, - }, - Line: { - edit: emptyWizard, - create: emptyWizard, - }, - Log: { - edit: emptyWizard, - create: emptyWizard, - }, - LogControl: { - edit: emptyWizard, - create: emptyWizard, - }, - LogSettings: { - edit: emptyWizard, - create: emptyWizard, - }, - MaxTime: { - edit: emptyWizard, - create: emptyWizard, - }, - McSecurity: { - edit: emptyWizard, - create: emptyWizard, - }, - MinTime: { - edit: emptyWizard, - create: emptyWizard, - }, - NeutralPoint: { - edit: emptyWizard, - create: emptyWizard, - }, - OptFields: { - edit: emptyWizard, - create: emptyWizard, - }, - P: { - edit: emptyWizard, - create: emptyWizard, - }, - PhysConn: { - edit: emptyWizard, - create: emptyWizard, - }, - PowerTransformer: { - edit: editPowerTransformerWizard, - create: emptyWizard, - }, - Private: { - edit: emptyWizard, - create: emptyWizard, - }, - Process: { - edit: emptyWizard, - create: emptyWizard, - }, - ProtNs: { - edit: emptyWizard, - create: emptyWizard, - }, - Protocol: { - edit: emptyWizard, - create: emptyWizard, - }, - ReadWrite: { - edit: emptyWizard, - create: emptyWizard, - }, - RedProt: { - edit: emptyWizard, - create: emptyWizard, - }, - ReportControl: { - edit: emptyWizard, - create: emptyWizard, - }, - ReportSettings: { - edit: emptyWizard, - create: emptyWizard, - }, - RptEnabled: { - edit: emptyWizard, - create: emptyWizard, - }, - SamplesPerSec: { - edit: emptyWizard, - create: emptyWizard, - }, - SampledValueControl: { - edit: emptyWizard, - create: emptyWizard, - }, - SecPerSamples: { - edit: emptyWizard, - create: emptyWizard, - }, - SCL: { - edit: emptyWizard, - create: emptyWizard, - }, - SDI: { - edit: emptyWizard, - create: emptyWizard, - }, - SDO: { - edit: emptyWizard, - create: emptyWizard, - }, - Server: { - edit: emptyWizard, - create: emptyWizard, - }, - ServerAt: { - edit: emptyWizard, - create: emptyWizard, - }, - Services: { - edit: emptyWizard, - create: emptyWizard, - }, - SetDataSetValue: { - edit: emptyWizard, - create: emptyWizard, - }, - SettingControl: { - edit: emptyWizard, - create: emptyWizard, - }, - SettingGroups: { - edit: emptyWizard, - create: emptyWizard, - }, - SGEdit: { - edit: emptyWizard, - create: emptyWizard, - }, - SmpRate: { - edit: emptyWizard, - create: emptyWizard, - }, - SMV: { - edit: emptyWizard, - create: emptyWizard, - }, - SmvOpts: { - edit: emptyWizard, - create: emptyWizard, - }, - SMVsc: { - edit: emptyWizard, - create: emptyWizard, - }, - SMVSecurity: { - edit: emptyWizard, - create: emptyWizard, - }, - SMVSettings: { - edit: emptyWizard, - create: emptyWizard, - }, - SubEquipment: { - edit: emptyWizard, - create: emptyWizard, - }, - SubFunction: { - edit: emptyWizard, - create: emptyWizard, - }, - SubNetwork: { - edit: emptyWizard, - create: emptyWizard, - }, - Subject: { - edit: emptyWizard, - create: emptyWizard, - }, - Substation: { - edit: emptyWizard, - create: emptyWizard, - }, - SupSubscription: { - edit: emptyWizard, - create: emptyWizard, - }, - TapChanger: { - edit: emptyWizard, - create: emptyWizard, - }, - Terminal: { - edit: editTerminalWizard, - create: emptyWizard, - }, - Text: { - edit: emptyWizard, - create: emptyWizard, - }, - TimerActivatedControl: { - edit: emptyWizard, - create: emptyWizard, - }, - TimeSyncProt: { - edit: emptyWizard, - create: emptyWizard, - }, - TransformerWinding: { - edit: emptyWizard, - create: emptyWizard, - }, - TrgOps: { - edit: emptyWizard, - create: emptyWizard, - }, - Val: { - edit: emptyWizard, - create: emptyWizard, - }, - ValueHandling: { - edit: emptyWizard, - create: emptyWizard, - }, - Voltage: { - edit: emptyWizard, - create: emptyWizard, - }, - VoltageLevel: { - edit: emptyWizard, - create: emptyWizard, - }, -}; diff --git a/packages/plugins/src/editors/subscription/fcda-binding-list.ts b/packages/plugins/src/editors/subscription/fcda-binding-list.ts deleted file mode 100644 index 4843785f7a..0000000000 --- a/packages/plugins/src/editors/subscription/fcda-binding-list.ts +++ /dev/null @@ -1,460 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - PropertyValues, - query, - state, - TemplateResult, -} from 'lit-element'; -import { nothing, SVGTemplateResult } from 'lit-html'; -import { classMap } from 'lit-html/directives/class-map.js'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-list/mwc-check-list-item'; -import '@material/mwc-menu'; -import '@material/mwc-icon-button'; - -import { Icon } from '@material/mwc-icon'; -import { List } from '@material/mwc-list'; -import { Menu } from '@material/mwc-menu'; - -import { - getDescriptionAttribute, - getNameAttribute, - identity, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { gooseIcon, smvIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { wizards } from '../../wizards/wizard-library.js'; - -import { - getFcdaSubtitleValue, - getFcdaTitleValue, - newFcdaSelectEvent, - styles, - SubscriptionChangedEvent, -} from './foundation.js'; -import { getSubscribedExtRefElements } from './later-binding/foundation.js'; - -type controlTag = 'SampledValueControl' | 'GSEControl'; - -type iconLookup = Record; - -/** - * A sub element for showing all Goose/Sampled Value Controls. - * A control can be edited using the standard wizard. - * And when selecting a FCDA Element a custom event is fired, so other list can be updated. - */ -@customElement('fcda-binding-list') -export class FcdaBindingList extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property() - controlTag!: controlTag; - @property() - includeLaterBinding!: boolean; - - // The selected Elements when a FCDA Line is clicked. - @state() - private selectedControlElement: Element | undefined; - @state() - private selectedFcdaElement: Element | undefined; - @state() - private extRefCounters = new Map(); - - @property({ - type: Boolean, - hasChanged() { - return false; - }, - }) - get hideSubscribed(): boolean { - return ( - localStorage.getItem( - `fcda-binding-list-${ - this.includeLaterBinding ? 'later-binding' : 'data-binding' - }-${this.controlTag}$hideSubscribed` - ) === 'true' ?? false - ); - } - - set hideSubscribed(value: boolean) { - const oldValue = this.hideSubscribed; - localStorage.setItem( - `fcda-binding-list-${ - this.includeLaterBinding ? 'later-binding' : 'data-binding' - }-${this.controlTag}$hideSubscribed`, - `${value}` - ); - this.requestUpdate('hideSubscribed', oldValue); - } - - @property({ - type: Boolean, - hasChanged() { - return false; - }, - }) - get hideNotSubscribed(): boolean { - return ( - localStorage.getItem( - `fcda-binding-list-${ - this.includeLaterBinding ? 'later-binding' : 'data-binding' - }-${this.controlTag}$hideNotSubscribed` - ) === 'true' ?? false - ); - } - - set hideNotSubscribed(value: boolean) { - const oldValue = this.hideNotSubscribed; - localStorage.setItem( - `fcda-binding-list-${ - this.includeLaterBinding ? 'later-binding' : 'data-binding' - }-${this.controlTag}$hideNotSubscribed`, - `${value}` - ); - this.requestUpdate('hideNotSubscribed', oldValue); - } - - @query('.actions-menu') actionsMenu!: Menu; - @query('.actions-menu-icon') actionsMenuIcon!: Icon; - @query('.control-block-list') controlBlockList!: List; - - private iconControlLookup: iconLookup = { - SampledValueControl: smvIcon, - GSEControl: gooseIcon, - }; - - constructor() { - super(); - - this.resetSelection = this.resetSelection.bind(this); - parent.addEventListener('open-doc', this.resetSelection); - - const parentDiv = this.closest('.container'); - if (parentDiv) { - this.resetExtRefCount = this.resetExtRefCount.bind(this); - parentDiv.addEventListener('subscription-changed', this.resetExtRefCount); - } - } - - private getControlElements(): Element[] { - if (this.doc) { - return Array.from(this.doc.querySelectorAll(`LN0 > ${this.controlTag}`)); - } - return []; - } - - private getFcdaElements(controlElement: Element): Element[] { - const lnElement = controlElement.parentElement; - if (lnElement) { - return Array.from( - lnElement.querySelectorAll( - `:scope > DataSet[name=${controlElement.getAttribute( - 'datSet' - )}] > FCDA` - ) - ); - } - return []; - } - - private resetExtRefCount(event: SubscriptionChangedEvent): void { - if (event.detail.control && event.detail.fcda) { - const controlBlockFcdaId = `${identity(event.detail.control)} ${identity( - event.detail.fcda - )}`; - this.extRefCounters.delete(controlBlockFcdaId); - } - } - - private getExtRefCount( - fcdaElement: Element, - controlElement: Element - ): number { - const controlBlockFcdaId = `${identity(controlElement)} ${identity( - fcdaElement - )}`; - if (!this.extRefCounters.has(controlBlockFcdaId)) { - const extRefCount = getSubscribedExtRefElements( - this.doc.getRootNode(), - this.controlTag, - fcdaElement, - controlElement!, - this.includeLaterBinding - ).length; - this.extRefCounters.set(controlBlockFcdaId, extRefCount); - } - return this.extRefCounters.get(controlBlockFcdaId); - } - - private openEditWizard(controlElement: Element): void { - const wizard = wizards[this.controlTag].edit(controlElement); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private resetSelection(): void { - this.selectedControlElement = undefined; - this.selectedFcdaElement = undefined; - } - - private onFcdaSelect(controlElement: Element, fcdaElement: Element) { - this.resetSelection(); - - this.selectedControlElement = controlElement; - this.selectedFcdaElement = fcdaElement; - } - - protected updated(_changedProperties: PropertyValues): void { - super.updated(_changedProperties); - - // When a new document is loaded or the selection is changed - // we will fire the FCDA Select Event. - if ( - _changedProperties.has('doc') || - _changedProperties.has('selectedControlElement') || - _changedProperties.has('selectedFcdaElement') - ) { - this.dispatchEvent( - newFcdaSelectEvent( - this.selectedControlElement, - this.selectedFcdaElement - ) - ); - } - - // When a new document is loaded we will reset the Map to clear old entries. - if (_changedProperties.has('doc')) { - this.extRefCounters = new Map(); - } - } - - renderFCDA(controlElement: Element, fcdaElement: Element): TemplateResult { - const fcdaCount = this.getExtRefCount(fcdaElement, controlElement); - - const filterClasses = { - subitem: true, - 'show-subscribed': fcdaCount !== 0, - 'show-not-subscribed': fcdaCount === 0, - }; - - return html` this.onFcdaSelect(controlElement, fcdaElement)} - value="${identity(controlElement)} - ${identity(fcdaElement)}" - > - ${getFcdaTitleValue(fcdaElement)} - ${getFcdaSubtitleValue(fcdaElement)} - subdirectory_arrow_right - ${fcdaCount !== 0 ? html`${fcdaCount}` : nothing} - `; - } - - updateBaseFilterState(): void { - !this.hideSubscribed - ? this.controlBlockList!.classList.add('show-subscribed') - : this.controlBlockList!.classList.remove('show-subscribed'); - !this.hideNotSubscribed - ? this.controlBlockList!.classList.add('show-not-subscribed') - : this.controlBlockList!.classList.remove('show-not-subscribed'); - } - - protected firstUpdated(): void { - this.actionsMenu.anchor = this.actionsMenuIcon; - - this.actionsMenu.addEventListener('closed', () => { - this.hideSubscribed = !(>this.actionsMenu.index).has(0); - this.hideNotSubscribed = !(>this.actionsMenu.index).has(1); - this.updateBaseFilterState(); - }); - - this.updateBaseFilterState(); - } - - renderTitle(): TemplateResult { - const menuClasses = { - 'filter-off': this.hideSubscribed || this.hideNotSubscribed, - }; - return html`

    - ${get(`subscription.${this.controlTag}.controlBlockList.title`)} - { - if (!this.actionsMenu.open) this.actionsMenu.show(); - else this.actionsMenu.close(); - }} - > - - - ${get('subscription.subscriber.subscribed')} - - - ${get('subscription.subscriber.notSubscribed')} - - -

    `; - } - - renderControls(controlElements: Element[]): TemplateResult { - return html` - ${controlElements - .filter(controlElement => this.getFcdaElements(controlElement).length) - .map(controlElement => { - const fcdaElements = this.getFcdaElements(controlElement); - const showSubscribed = fcdaElements.some( - fcda => this.getExtRefCount(fcda, controlElement) !== 0 - ); - const showNotSubscribed = fcdaElements.some( - fcda => this.getExtRefCount(fcda, controlElement) === 0 - ); - - const filterClasses = { - control: true, - 'show-subscribed': showSubscribed, - 'show-not-subscribed': showNotSubscribed, - }; - - return html` - - this.openEditWizard(controlElement)} - > - ${getNameAttribute(controlElement)} - ${getDescriptionAttribute(controlElement) - ? html`${getDescriptionAttribute(controlElement)}` - : nothing} - ${identity(controlElement)} - ${this.iconControlLookup[this.controlTag]} - -
  • - ${fcdaElements.map(fcdaElement => - this.renderFCDA(controlElement, fcdaElement) - )} - `; - })} -
    `; - } - - render(): TemplateResult { - const controlElements = this.getControlElements(); - return html`
    - ${this.renderTitle()} - ${controlElements - ? this.renderControls(controlElements) - : html`

    ${get('subscription.subscriber.notSubscribed')}

    `} -
    `; - } - - static styles = css` - ${styles} - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - - mwc-list-item { - --mdc-list-item-meta-size: 48px; - } - - section { - position: relative; - } - - .actions-menu-icon { - float: right; - } - - .actions-menu-icon.filter-off { - color: var(--secondary); - background-color: var(--mdc-theme-background); - } - - /* Filtering rules for control blocks end up implementing logic to allow - very fast CSS response. The following rules appear to be minimal but can be - hard to understand intuitively for the multiple conditions. If modifying, - it is suggested to create a truth-table to check for side-effects */ - - /* remove all control blocks if no filters */ - filtered-list.control-block-list:not(.show-subscribed, .show-not-subscribed) - mwc-list-item { - display: none; - } - - /* remove control blocks taking care to respect multiple conditions */ - filtered-list.control-block-list.show-not-subscribed:not(.show-subscribed) - mwc-list-item.control.show-subscribed:not(.show-not-subscribed) { - display: none; - } - - filtered-list.control-block-list.show-subscribed:not(.show-not-subscribed) - mwc-list-item.control.show-not-subscribed:not(.show-subscribed) { - display: none; - } - - /* remove fcdas if not part of filter */ - filtered-list.control-block-list:not(.show-not-subscribed) - mwc-list-item.subitem.show-not-subscribed { - display: none; - } - - filtered-list.control-block-list:not(.show-subscribed) - mwc-list-item.subitem.show-subscribed { - display: none; - } - - .interactive { - pointer-events: all; - } - - .subitem { - padding-left: var(--mdc-list-side-padding, 16px); - } - `; -} diff --git a/packages/plugins/src/editors/subscription/foundation.ts b/packages/plugins/src/editors/subscription/foundation.ts deleted file mode 100644 index 739678d5df..0000000000 --- a/packages/plugins/src/editors/subscription/foundation.ts +++ /dev/null @@ -1,1009 +0,0 @@ -import { css, LitElement, query } from 'lit-element'; - -import { - compareNames, - getSclSchemaVersion, - isPublic, - minAvailableLogicalNodeInstance, -} from '@openscd/open-scd/src/foundation.js'; - -import { - cloneElement, - createElement, -} from '@openscd/xml'; - -import { Create, Delete } from '@openscd/core/foundation/deprecated/editor.js'; -import { getFcdaReferences } from '@openscd/open-scd/src/foundation/ied.js'; -import { SCL_NAMESPACE } from '@openscd/open-scd/src/schemas.js'; - -export enum View { - PUBLISHER, - SUBSCRIBER, -} - -/** - * Enumeration stating the Subscribe status of a IED to a GOOSE or Sampled Value. - */ -export enum SubscribeStatus { - Full, - Partial, - None, -} - -export interface ViewDetail { - view: View; -} -export type ViewEvent = CustomEvent; -export function newViewEvent( - view: View, - eventInitDict?: CustomEventInit -): ViewEvent { - return new CustomEvent('view', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { view, ...eventInitDict?.detail }, - }); -} - -export interface IEDSelectDetail { - ied: Element | undefined; -} -export type IEDSelectEvent = CustomEvent; -export function newIEDSelectEvent( - ied: Element | undefined, - eventInitDict?: CustomEventInit -): IEDSelectEvent { - return new CustomEvent('ied-select', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { ied, ...eventInitDict?.detail }, - }); -} - -export interface FcdaSelectDetail { - control: Element | undefined; - fcda: Element | undefined; -} -export type FcdaSelectEvent = CustomEvent; -export function newFcdaSelectEvent( - control: Element | undefined, - fcda: Element | undefined, - eventInitDict?: CustomEventInit -): FcdaSelectEvent { - return new CustomEvent('fcda-select', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { control, fcda, ...eventInitDict?.detail }, - }); -} - -export interface SubscriptionChangedDetail { - control: Element | undefined; - fcda: Element | undefined; -} -export type SubscriptionChangedEvent = CustomEvent; -export function newSubscriptionChangedEvent( - control: Element | undefined, - fcda: Element | undefined, - eventInitDict?: CustomEventInit -): SubscriptionChangedEvent { - return new CustomEvent('subscription-changed', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { control, fcda, ...eventInitDict?.detail }, - }); -} - -export function getFcdaTitleValue(fcdaElement: Element): string { - return `${fcdaElement.getAttribute('doName')}${ - fcdaElement.hasAttribute('doName') && fcdaElement.hasAttribute('daName') - ? `.` - : `` - }${fcdaElement.getAttribute('daName')}`; -} - -export function getFcdaSubtitleValue(fcdaElement: Element): string { - return `${fcdaElement.getAttribute('ldInst')} ${ - fcdaElement.hasAttribute('ldInst') ? `/` : '' - }${ - fcdaElement.getAttribute('prefix') - ? ` ${fcdaElement.getAttribute('prefix')}` - : '' - } ${fcdaElement.getAttribute('lnClass')} ${fcdaElement.getAttribute( - 'lnInst' - )}`; -} - -export function existExtRef( - parentInputs: Element, - fcda: Element, - control: Element | undefined -): boolean { - return !!getExtRef(parentInputs, fcda, control); -} - -export function getExtRef( - parentInputs: Element, - fcda: Element, - control: Element | undefined -): Element | undefined { - function createCriteria(attributeName: string, value: string | null): string { - // For ExtRef the attribute 'srcLNClass' is optional and defaults to 'LLN0', here we ignore 'srcLNClass' completely for 'LLN0' - // because otherwise we would have to extend the querySelector to multiple selector groups checking for 'LLN0' or missing 'srcLNClass' - const shouldIgnoreCriteria = attributeName === 'srcLNClass' && value === 'LLN0'; - if (shouldIgnoreCriteria) { - return ''; - } - - if (value) { - return `[${attributeName}="${value}"]`; - } - return ''; - } - - const iedName = fcda.closest('IED')?.getAttribute('name'); - if (!iedName) { - return undefined; - } - - let controlCriteria = ''; - if (control && getSclSchemaVersion(fcda.ownerDocument) !== '2003') { - controlCriteria = `[serviceType="${serviceTypes[control.tagName]!}"]`; - controlCriteria += createCriteria( - 'srcLDInst', - control.closest('LDevice')?.getAttribute('inst') ?? null - ); - controlCriteria += createCriteria( - 'srcLNClass', - control.closest('LN0,LN')?.getAttribute('lnClass') ?? null - ); - controlCriteria += createCriteria( - 'srcLNInst', - control.closest('LN0,LN')?.getAttribute('inst') ?? null - ); - controlCriteria += createCriteria( - 'srcCBName', - control.getAttribute('name') ?? null - ); - } - - return Array.from( - parentInputs.querySelectorAll( - `ExtRef[iedName="${iedName}"]${getFcdaReferences(fcda)}${controlCriteria}` - ) - ).find(extRefElement => !extRefElement.hasAttribute('intAddr')); -} - -export function canRemoveSubscriptionSupervision( - subscribedExtRef: Element -): boolean { - const [srcCBName, srcLDInst, srcLNClass, iedName, srcPrefix, srcLNInst] = [ - 'srcCBName', - 'srcLDInst', - 'srcLNClass', - 'iedName', - 'srcPrefix', - 'srcLNInst', - ].map(attr => subscribedExtRef.getAttribute(attr)); - return !Array.from( - subscribedExtRef.closest('IED')?.getElementsByTagName('ExtRef') ?? [] - ) - .filter(isPublic) - .some( - extRef => - (extRef.getAttribute('srcCBName') ?? '') === (srcCBName ?? '') && - (extRef.getAttribute('srcLDInst') ?? '') === (srcLDInst ?? '') && - (extRef.getAttribute('srcLNClass') ?? '') === (srcLNClass ?? '') && - (extRef.getAttribute('iedName') ?? '') === (iedName ?? '') && - (extRef.getAttribute('srcPrefix') ?? '') === (srcPrefix ?? '') && - (extRef.getAttribute('srcLNInst') ?? '') === (srcLNInst ?? '') && - extRef !== subscribedExtRef - ); -} - -/** - * Searches for first instantiated LGOS/LSVS LN for presence of DOI>DAI[valKind=Conf/RO][valImport=true] - * given a supervision type and if necessary then searches DataTypeTemplates for - * DOType>DA[valKind=Conf/RO][valImport=true] to determine if modifications to supervision are allowed. - * @param ied - SCL IED element. - * @param supervisionType - either 'LGOS' or 'LSVS' supervision LN classes. - * @returns boolean indicating if subscriptions are allowed. - */ -function isSupervisionModificationAllowed( - ied: Element, - supervisionType: string -): boolean { - const firstSupervisionLN = ied.querySelector( - `LN[lnClass="${supervisionType}"]` - ); - - // no supervision logical nodes => no new supervision possible - if (firstSupervisionLN === null) return false; - - // check if allowed to modify based on first instance properties - const supervisionName = supervisionType === 'LGOS' ? 'GoCBRef' : 'SvCBRef'; - const instValKind = firstSupervisionLN! - .querySelector(`DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]`) - ?.getAttribute('valKind'); - const instValImport = firstSupervisionLN! - .querySelector(`DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]`) - ?.getAttribute('valImport'); - - if ( - (instValKind === 'RO' || instValKind === 'Conf') && - instValImport === 'true' - ) - return true; - - // check if allowed to modify based on DataTypeTemplates for first instance - const rootNode = firstSupervisionLN?.ownerDocument; - const lNodeType = firstSupervisionLN.getAttribute('lnType'); - const lnClass = firstSupervisionLN.getAttribute('lnClass'); - const dObj = rootNode.querySelector( - `DataTypeTemplates > LNodeType[id="${lNodeType}"][lnClass="${lnClass}"] > DO[name="${ - lnClass === 'LGOS' ? 'GoCBRef' : 'SvCBRef' - }"]` - ); - if (dObj) { - const dORef = dObj.getAttribute('type'); - const daObj = rootNode.querySelector( - `DataTypeTemplates > DOType[id="${dORef}"] > DA[name="setSrcRef"]` - ); - if (daObj) { - return ( - (daObj.getAttribute('valKind') === 'Conf' || - daObj.getAttribute('valKind') === 'RO') && - daObj.getAttribute('valImport') === 'true' - ); - } - } - // definition missing - return false; -} - -/** - * Returns an array with a single Create action to create a new - * supervision element for the given GOOSE/SMV message and subscriber IED. - * - * @param controlBlock The GOOSE or SMV message element - * @param subscriberIED The subscriber IED - * @returns an empty array if instantiation is not possible or an array with a single Create action - */ -export function instantiateSubscriptionSupervision( - controlBlock: Element | undefined, - subscriberIED: Element | undefined -): Create[] { - const supervisionType = - controlBlock?.tagName === 'GSEControl' ? 'LGOS' : 'LSVS'; - if ( - !controlBlock || - !subscriberIED || - !isSupervisionAllowed(controlBlock, subscriberIED, supervisionType) - ) - return []; - const availableLN = findOrCreateAvailableLNInst( - controlBlock, - subscriberIED, - supervisionType - ); - if ( - !availableLN || - !isSupervisionModificationAllowed(subscriberIED, supervisionType) - ) - return []; - - const actions: Create[] = []; - // If creating new LN element - if (!availableLN.parentElement) { - const parent = subscriberIED.querySelector( - `LN[lnClass="${supervisionType}"]` - )?.parentElement; - if (parent) { - // use Create Action for supervision LN - actions.push({ - new: { - parent: parent, - element: availableLN, - reference: parent!.querySelector( - `LN[lnClass="${supervisionType}"]:last-child` - )?.nextElementSibling, - }, - }); - } - } - - // Create child elements - const supervisionName = supervisionType === 'LGOS' ? 'GoCBRef' : 'SvCBRef'; - - let doiElement = availableLN.querySelector(`DOI[name="${supervisionName}"]`); - if (!doiElement) { - doiElement = subscriberIED.ownerDocument.createElementNS( - SCL_NAMESPACE, - 'DOI' - ); - doiElement.setAttribute('name', supervisionName); - actions.push({ - new: { - parent: availableLN!, - element: doiElement, - }, - }); - } - - let daiElement = availableLN.querySelector( - `DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]` - ); - if (!daiElement) { - daiElement = subscriberIED.ownerDocument.createElementNS( - SCL_NAMESPACE, - 'DAI' - ); - const srcValRef = subscriberIED.querySelector( - `LN[lnClass="${supervisionType}"]>DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]` - ); - daiElement.setAttribute('name', 'setSrcRef'); - - // transfer valKind and valImport from first supervision instance if present - if (srcValRef?.hasAttribute('valKind')) - daiElement.setAttribute('valKind', srcValRef.getAttribute('valKind')!); - if (srcValRef?.hasAttribute('valImport')) - daiElement.setAttribute( - 'valImport', - srcValRef.getAttribute('valImport')! - ); - actions.push({ - new: { - parent: doiElement!, - element: daiElement, - }, - }); - } - - let valElement = availableLN.querySelector(`Val`); - if (!valElement) { - valElement = subscriberIED.ownerDocument.createElementNS( - SCL_NAMESPACE, - 'Val' - ); - } - valElement.textContent = controlBlockReference(controlBlock); - actions.push({ - new: { - parent: daiElement!, - element: valElement, - }, - }); - - return actions; -} - -/** - * Return Val elements within an LGOS/LSVS instance for a particular IED and control block type. - * @param ied - IED SCL element. - * @param cbTagName - Either GSEControl or (defaults to) SampledValueControl. - * @param firstOnly - If true, return the first element found - * @returns an Element array of Val SCL elements within an LGOS/LSVS node. - */ -export function getSupervisionCbRefs( - ied: Element, - cbTagName: string -): Element[]; -export function getSupervisionCbRefs( - ied: Element, - cbTagName: string, - firstOnly: boolean -): Element | null; -export function getSupervisionCbRefs( - ied: Element, - cbTagName: string, - firstOnly?: boolean -): Element[] | Element | null { - const supervisionType = cbTagName === 'GSEControl' ? 'LGOS' : 'LSVS'; - const supervisionName = supervisionType === 'LGOS' ? 'GoCBRef' : 'SvCBRef'; - const selectorString = `LN[lnClass="${supervisionType}"]>DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]>Val,LN0[lnClass="${supervisionType}"]>DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]>Val`; - return firstOnly - ? ied.querySelector(selectorString) - : Array.from(ied.querySelectorAll(selectorString)); -} - -/** - * Return an array with a single Delete action to delete the supervision element - * for the given GOOSE/SMV message and subscriber IED. - * - * @param controlBlock The GOOSE or SMV message element - * @param subscriberIED The subscriber IED - * @returns an empty array if removing the supervision is not possible or an array - * with a single Delete action that removes the LN if it was created in OpenSCD - * or only the supervision structure DOI/DAI/Val if it was created by the user. - */ -export function removeSubscriptionSupervision( - controlBlock: Element | undefined, - subscriberIED: Element | undefined -): Delete[] { - if (!controlBlock || !subscriberIED) return []; - const valElement = getSupervisionCbRefs( - subscriberIED, - controlBlock.tagName - ).find(val => val.textContent == controlBlockReference(controlBlock)); - if (!valElement) return []; - const lnElement = valElement.closest('LN0, LN'); - if (!lnElement || !lnElement.parentElement) return []; - // Check if that one has been created by OpenSCD (private section exists) - const isOpenScdCreated = lnElement.querySelector( - 'Private[type="OpenSCD.create"]' - ); - return isOpenScdCreated - ? [ - { - old: { - parent: lnElement.parentElement, - element: lnElement, - }, - }, - ] - : [ - { - old: { - parent: lnElement, - element: valElement.closest('DOI')!, - }, - }, - ]; -} - -/** - * Checks if the given combination of GOOSE/SMV message and subscriber IED - * allows for subscription supervision. - * @param controlBlock The GOOSE or SMV message element - * @param subscriberIED The subscriber IED - * @param supervisionType LSVS or LGOS - * @returns true if both controlBlock and subscriberIED meet the requirements for - * setting up a supervision for the specified supervision type or false if they don't - */ -function isSupervisionAllowed( - controlBlock: Element, - subscriberIED: Element, - supervisionType: string -): boolean { - if (getSclSchemaVersion(subscriberIED.ownerDocument) === '2003') return false; - if (subscriberIED.querySelector(`LN[lnClass="${supervisionType}"]`) === null) - return false; - if ( - getSupervisionCbRefs(subscriberIED, controlBlock.tagName).find( - val => val.textContent == controlBlockReference(controlBlock) - ) - ) - return false; - if ( - maxSupervisions(subscriberIED, controlBlock) <= - instantiatedSupervisionsCount(subscriberIED, controlBlock) - ) - return false; - - return true; -} - -/** Returns an new or existing LN instance available for supervision instantiation - * - * @param controlBlock The GOOSE or SMV message element - * @param subscriberIED The subscriber IED - * @returns The LN instance or null if no LN instance could be found or created - */ -export function findOrCreateAvailableLNInst( - controlBlock: Element, - subscriberIED: Element, - supervisionType: string -): Element | null { - let availableLN = Array.from( - subscriberIED.querySelectorAll(`LN[lnClass="${supervisionType}"]`) - ).find(ln => { - const supervisionName = supervisionType === 'LGOS' ? 'GoCBRef' : 'SvCBRef'; - return ( - ln.querySelector( - `DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]>Val` - ) === null || - ln.querySelector( - `DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]>Val` - )?.textContent === '' - ); - }); - if (!availableLN) { - availableLN = subscriberIED.ownerDocument.createElementNS( - SCL_NAMESPACE, - 'LN' - ); - const openScdTag = subscriberIED.ownerDocument.createElementNS( - SCL_NAMESPACE, - 'Private' - ); - openScdTag.setAttribute('type', 'OpenSCD.create'); - availableLN.appendChild(openScdTag); - availableLN.setAttribute('lnClass', supervisionType); - const instantiatedSiblings = getSupervisionCbRefs( - subscriberIED, - controlBlock.tagName, - true - )?.closest('LN'); - - if (!instantiatedSiblings) return null; - availableLN.setAttribute( - 'lnType', - instantiatedSiblings?.getAttribute('lnType') ?? '' - ); - } - - /* Before we return, we make sure that LN's inst is unique, non-empty - and also the minimum inst as the minimum of all available in the IED */ - const inst = availableLN.getAttribute('inst') ?? ''; - if (inst === '') { - const instNumber = minAvailableLogicalNodeInstance( - Array.from( - subscriberIED.querySelectorAll(`LN[lnClass="${supervisionType}"]`) - ) - ); - if (!instNumber) return null; - availableLN.setAttribute('inst', instNumber); - } - return availableLN; -} - -/** - * Find the first ExtRef SCL element given a control and a subscribing IED - * - * @param publishedControlBlock - the control block SCL element in the publishing IED. - * @param subscribingIed - the subscribing IED SCL element. - * @returns The first ExtRef element associated with the subscribing IED and published control block. - */ -export function getFirstSubscribedExtRef( - publishedControlBlock: Element, - subscribingIed: Element -): Element | null { - const publishingIed = publishedControlBlock.closest('LN,LN0')!; - const dataSet = publishingIed.querySelector( - `DataSet[name="${publishedControlBlock.getAttribute('datSet')}"]` - ); - let extRef: Element | undefined = undefined; - Array.from( - subscribingIed?.querySelectorAll('LN0 > Inputs, LN > Inputs') - ).some(inputs => { - Array.from(dataSet!.querySelectorAll('FCDA')).some(fcda => { - const anExtRef = getExtRef(inputs, fcda, publishedControlBlock); - if (anExtRef) { - extRef = anExtRef; - return true; - } - return false; - }); - return extRef !== undefined; - }); - return extRef !== undefined ? extRef : null; -} - -/** Returns the subscriber's supervision LN for a given control block and extRef element - * - * @param extRef - The extRef SCL element in the subscribing IED. - * @returns The supervision LN instance or null if not found - */ -export function getExistingSupervision(extRef: Element | null): Element | null { - if (extRef === null) return null; - - const extRefValues = ['iedName', 'serviceType', 'srcPrefix', 'srcCBName']; - const [srcIedName, serviceType, srcPrefix, srcCBName] = extRefValues.map( - attr => extRef.getAttribute(attr) ?? '' - ); - - const supervisionType = serviceType === 'GOOSE' ? 'LGOS' : 'LSVS'; - const refSelector = - supervisionType === 'LGOS' ? 'DOI[name="GoCBRef"]' : 'DOI[name="SvCBRef"]'; - - const srcLDInst = - extRef.getAttribute('srcLDInst') ?? extRef.getAttribute('ldInst'); - const srcLNClass = extRef.getAttribute('srcLNClass') ?? 'LLN0'; - - const cbReference = `${srcIedName}${srcPrefix}${srcLDInst}/${srcLNClass}.${srcCBName}`; - const iedName = extRef.closest('IED')?.getAttribute('name'); - - const candidates = Array.from( - extRef.ownerDocument - .querySelector(`IED[name="${iedName}"]`)! - .querySelectorAll( - `LN[lnClass="${supervisionType}"]>${refSelector}>DAI[name="setSrcRef"]>Val` - ) - ).find(val => val.textContent === cbReference); - - return candidates !== undefined ? candidates.closest('LN')! : null; -} - -/** - * Counts the number of LN instances with proper supervision for the given control block set up. - * - * @param subscriberIED The subscriber IED - * @param controlBlock The GOOSE or SMV message element - * @returns The number of LN instances with a supervision set up - */ -export function instantiatedSupervisionsCount( - subscriberIED: Element, - controlBlock: Element -): number { - const instantiatedValues = getSupervisionCbRefs( - subscriberIED, - controlBlock.tagName - ).filter(val => val.textContent !== ''); - return instantiatedValues.length; -} - -/** - * Counts the max number of LN instances with supervision allowed for - * the given control block's type of message. - * - * @param subscriberIED The subscriber IED - * @param controlBlock The GOOSE or SMV message element - * @returns The max number of LN instances with supervision allowed - */ -export function maxSupervisions( - subscriberIED: Element, - controlBlock: Element -): number { - const maxAttr = controlBlock.tagName === 'GSEControl' ? 'maxGo' : 'maxSv'; - const maxValues = parseInt( - subscriberIED - .querySelector('Services>SupSubscription') - ?.getAttribute(maxAttr) ?? '0', - 10 - ); - return isNaN(maxValues) ? 0 : maxValues; -} - -/** - * Creates a string pointer to the control block element. - * - * @param controlBlock The GOOSE or SMV message element - * @returns null if the control block is undefined or a string pointer to the control block element - */ -export function controlBlockReference( - controlBlock: Element | undefined -): string | null { - if (!controlBlock) return null; - const anyLn = controlBlock.closest('LN,LN0'); - const prefix = anyLn?.getAttribute('prefix') ?? ''; - const lnClass = anyLn?.getAttribute('lnClass'); - const lnInst = anyLn?.getAttribute('inst') ?? ''; - const ldInst = controlBlock.closest('LDevice')?.getAttribute('inst'); - const iedName = controlBlock.closest('IED')?.getAttribute('name'); - const cbName = controlBlock.getAttribute('name'); - if (!cbName && !iedName && !ldInst && !lnClass) return null; - return `${iedName}${ldInst}/${prefix}${lnClass}${lnInst}.${cbName}`; -} - -export function canCreateValidExtRef( - fcda: Element, - controlBlock: Element | undefined -): boolean { - const iedName = fcda.closest('IED')?.getAttribute('name'); - const [ldInst, lnClass, lnInst, doName] = [ - 'ldInst', - 'lnClass', - 'lnInst', - 'doName', - ].map(attr => fcda.getAttribute(attr)); - if (!iedName || !ldInst || !lnClass || !lnInst || !doName) { - return false; - } - - // For 2003 schema or serviceType `Poll`, the extra fields aren't needed. - if ( - getSclSchemaVersion(fcda.ownerDocument) === '2003' || - controlBlock === undefined - ) { - return true; - } - - const srcLDInst = controlBlock.closest('LDevice')?.getAttribute('inst'); - const srcLNClass = controlBlock.closest('LN0,LN')?.getAttribute('lnClass'); - const srcLNInst = controlBlock.closest('LN0,LN')?.getAttribute('inst'); - const srcCBName = controlBlock.getAttribute('name'); - - // For srcLNInst an empty string is allowed in `LN0` - return !( - !srcLDInst || - !srcLNClass || - !srcCBName || - typeof srcLNInst !== 'string' - ); -} - -export const serviceTypes: Partial> = { - ReportControl: 'Report', - GSEControl: 'GOOSE', - SampledValueControl: 'SMV', -}; - -/** - * Create a new ExtRef Element depending on the SCL Edition copy attributes from the Control Element, - * FCDA Element and related Elements. - * - * @param controlElement - `ReportControl`, `GSEControl` or `SampledValueControl` source element - * @param fcdaElement - The source data attribute element. - * @returns The new created ExtRef element, which can be added to the document. - */ -export function createExtRefElement( - controlElement: Element | undefined, - fcdaElement: Element -): Element { - const iedName = fcdaElement.closest('IED')?.getAttribute('name') ?? null; - const [ldInst, prefix, lnClass, lnInst, doName, daName] = [ - 'ldInst', - 'prefix', - 'lnClass', - 'lnInst', - 'doName', - 'daName', - ].map(attr => fcdaElement.getAttribute(attr)); - - if (getSclSchemaVersion(fcdaElement.ownerDocument) === '2003') { - // Edition 2003(1) does not define serviceType and its MCD attribute starting with src... - return createElement(fcdaElement.ownerDocument, 'ExtRef', { - iedName, - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - }); - } - - if (!controlElement || !serviceTypes[controlElement.tagName]) { - //for invalid control block tag name assume polling - return createElement(fcdaElement.ownerDocument, 'ExtRef', { - iedName, - serviceType: 'Poll', - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - }); - } - - // default is empty string as attributes are mandatory acc to IEC 61850-6 >Ed2 - const srcLDInst = - controlElement.closest('LDevice')?.getAttribute('inst') ?? ''; - const srcPrefix = - controlElement.closest('LN0,LN')?.getAttribute('prefix') ?? ''; - const srcLNClass = - controlElement.closest('LN0,LN')?.getAttribute('lnClass') ?? ''; - const srcLNInst = controlElement.closest('LN0,LN')?.getAttribute('inst'); - const srcCBName = controlElement.getAttribute('name') ?? ''; - - return createElement(fcdaElement.ownerDocument, 'ExtRef', { - iedName, - serviceType: serviceTypes[controlElement.tagName]!, - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - srcLDInst, - srcPrefix, - srcLNClass, - srcLNInst: srcLNInst ? srcLNInst : null, - srcCBName, - }); -} - -/** - * Create a clone of the passed ExtRefElement and updated or set the required attributes on the cloned element - * depending on the Edition and type of Control Element. - * - * @param extRefElement - The ExtRef Element to clone and update. - * @param controlElement - `ReportControl`, `GSEControl` or `SampledValueControl` source element - * @param fcdaElement - The source data attribute element. - * @returns A cloned ExtRef Element with updated information to be used for example in a Replace Action. - */ -export function updateExtRefElement( - extRefElement: Element, - controlElement: Element | undefined, - fcdaElement: Element -): Element { - const iedName = fcdaElement.closest('IED')?.getAttribute('name') ?? null; - const [ldInst, prefix, lnClass, lnInst, doName, daName] = [ - 'ldInst', - 'prefix', - 'lnClass', - 'lnInst', - 'doName', - 'daName', - ].map(attr => fcdaElement.getAttribute(attr)); - - if (getSclSchemaVersion(fcdaElement.ownerDocument) === '2003') { - // Edition 2003(1) does not define serviceType and its MCD attribute starting with src... - return cloneElement(extRefElement, { - iedName, - serviceType: null, - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - srcLDInst: null, - srcPrefix: null, - srcLNClass: null, - srcLNInst: null, - srcCBName: null, - }); - } - - if (!controlElement || !serviceTypes[controlElement.tagName]) { - //for invalid control block tag name assume polling - return cloneElement(extRefElement, { - iedName, - serviceType: 'Poll', - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - srcLDInst: null, - srcPrefix: null, - srcLNClass: null, - srcLNInst: null, - srcCBName: null, - }); - } - - const srcLDInst = - controlElement.closest('LDevice')?.getAttribute('inst') ?? ''; - const srcPrefix = - controlElement.closest('LN0,LN')?.getAttribute('prefix') ?? ''; - const srcLNClass = - controlElement.closest('LN0,LN')?.getAttribute('lnClass') ?? ''; - const srcLNInst = controlElement.closest('LN0,LN')?.getAttribute('inst'); - const srcCBName = controlElement.getAttribute('name') ?? ''; - - return cloneElement(extRefElement, { - iedName, - serviceType: serviceTypes[controlElement.tagName]!, - ldInst, - lnClass, - lnInst, - prefix, - doName, - daName, - srcLDInst, - srcPrefix, - srcLNClass, - srcLNInst: srcLNInst ? srcLNInst : null, - srcCBName, - }); -} - -export function getOrderedIeds(doc: XMLDocument): Element[] { - return doc - ? Array.from(doc.querySelectorAll(':root > IED')).sort((a, b) => - compareNames(a, b) - ) - : []; -} - -/** - * An element within this list has 2 properties: - * - The element itself, either a GSEControl or an IED at this point. - * - A 'partial' property indicating if the GOOSE is fully initialized or partially. - */ -export interface ListElement { - element: Element; - partial?: boolean; -} - -export class SubscriberListContainer extends LitElement { - /** List holding all current subscribed Elements. */ - subscribedElements: ListElement[] = []; - - /** List holding all current available Elements which are not subscribed. */ - availableElements: ListElement[] = []; - - /** Current selected IED (when in Subscriber view) */ - currentSelectedIed: Element | undefined; - - /** The current used dataset for subscribing / unsubscribing */ - currentUsedDataset: Element | undefined | null; - - @query('div') subscriberWrapper!: Element; - - protected updated(): void { - if (this.subscriberWrapper) { - this.subscriberWrapper.scrollTo(0, 0); - } - } - - protected resetElements(): void { - this.subscribedElements = []; - this.availableElements = []; - } -} - -/** Common `CSS` styles used by DataTypeTemplate subeditors */ -export const styles = css` - :host(.moving) section { - opacity: 0.3; - } - - section { - background-color: var(--mdc-theme-surface); - transition: all 200ms linear; - outline-color: var(--mdc-theme-primary); - outline-style: solid; - outline-width: 0px; - opacity: 1; - } - - section:focus { - box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); - } - - section:focus-within { - outline-width: 2px; - transition: all 250ms linear; - } - - h1, - h2, - h3 { - color: var(--mdc-theme-on-surface); - font-family: 'Roboto', sans-serif; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin: 0px; - line-height: 48px; - padding-left: 0.3em; - transition: background-color 150ms linear; - } - - section:focus-within > h1, - section:focus-within > h2, - section:focus-within > h3 { - color: var(--mdc-theme-surface); - background-color: var(--mdc-theme-primary); - transition: background-color 200ms linear; - } - - h1 > nav, - h2 > nav, - h3 > nav, - h1 > abbr > mwc-icon-button, - h2 > abbr > mwc-icon-button, - h3 > abbr > mwc-icon-button { - float: right; - } - - abbr[title] { - border-bottom: none !important; - cursor: inherit !important; - text-decoration: none !important; - } - - mwc-list-item[noninteractive] { - font-weight: 500; - } -`; - -declare global { - interface ElementEventMap { - ['view']: ViewEvent; - ['ied-select']: IEDSelectEvent; - ['fcda-select']: FcdaSelectEvent; - ['subscription-changed']: SubscriptionChangedEvent; - } -} diff --git a/packages/plugins/src/editors/subscription/goose/foundation.ts b/packages/plugins/src/editors/subscription/goose/foundation.ts deleted file mode 100644 index c833d11b93..0000000000 --- a/packages/plugins/src/editors/subscription/goose/foundation.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { SubscribeStatus } from '../foundation.js'; - -export interface GOOSESelectDetail { - gseControl: Element | undefined; - dataset: Element | undefined; -} -export type GOOSESelectEvent = CustomEvent; -export function newGOOSESelectEvent( - gseControl: Element | undefined, - dataset: Element | undefined, - eventInitDict?: CustomEventInit -): GOOSESelectEvent { - return new CustomEvent('goose-select', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { gseControl, dataset, ...eventInitDict?.detail }, - }); -} - -export interface GooseSubscriptionDetail { - element: Element; - subscribeStatus: SubscribeStatus; -} -export type GooseSubscriptionEvent = CustomEvent; -export function newGooseSubscriptionEvent( - element: Element, - subscribeStatus: SubscribeStatus -): GooseSubscriptionEvent { - return new CustomEvent('goose-subscription', { - bubbles: true, - composed: true, - detail: { element, subscribeStatus }, - }); -} - -declare global { - interface ElementEventMap { - ['goose-select']: GOOSESelectEvent; - ['goose-subscription']: GooseSubscriptionEvent; - } -} diff --git a/packages/plugins/src/editors/subscription/goose/goose-list.ts b/packages/plugins/src/editors/subscription/goose/goose-list.ts deleted file mode 100644 index fc62afb4ad..0000000000 --- a/packages/plugins/src/editors/subscription/goose/goose-list.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; -import { classMap } from 'lit-html/directives/class-map'; - -import '@material/mwc-icon'; -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - getNameAttribute, - identity, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { newGOOSESelectEvent } from './foundation.js'; -import { gooseIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { wizards } from '../../../wizards/wizard-library.js'; -import { getOrderedIeds, styles } from '../foundation.js'; - -let selectedGseControl: Element | undefined; -let selectedDataSet: Element | undefined | null; - -function onOpenDocResetSelectedGooseMsg() { - selectedGseControl = undefined; - selectedDataSet = undefined; -} -addEventListener('open-doc', onOpenDocResetSelectedGooseMsg); - -/** An sub element for showing all published GOOSE messages per IED. */ -@customElement('goose-list') -export class GooseList extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - private onSelect(gseControl: Element): void { - if (gseControl == selectedGseControl) return; - - const ln = gseControl.parentElement; - const dataset = ln?.querySelector( - `DataSet[name=${gseControl.getAttribute('datSet')}]` - ); - - selectedGseControl = gseControl; - selectedDataSet = dataset; - - this.dispatchEvent( - newGOOSESelectEvent(selectedGseControl, selectedDataSet!) - ); - - this.requestUpdate(); - } - - renderGoose(gseControl: Element): TemplateResult { - return html` this.onSelect(gseControl)} - graphic="large" - hasMeta - value="${identity(gseControl)}" - > - ${gooseIcon} - ${gseControl.getAttribute('name')} - this.openEditWizard(gseControl)} - > - `; - } - - private openEditWizard(gseControl: Element): void { - const wizard = wizards['GSEControl'].edit(gseControl); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - protected updated(): void { - this.dispatchEvent( - newGOOSESelectEvent(selectedGseControl, selectedDataSet ?? undefined) - ); - } - - protected firstUpdated(): void { - selectedGseControl = undefined; - selectedDataSet = undefined; - } - - render(): TemplateResult { - return html`
    -

    ${get('subscription.goose.publisher.title')}

    - - ${getOrderedIeds(this.doc).map( - ied => - html` - - ${getNameAttribute(ied)} - developer_board - -
  • - ${Array.from( - ied.querySelectorAll( - ':scope > AccessPoint > Server > LDevice > LN0 > GSEControl' - ) - ) - .filter(cb => cb.hasAttribute('datSet')) - .map(control => this.renderGoose(control))} - ` - )} -
    -
    `; - } - - static styles = css` - ${styles} - - mwc-list-item { - --mdc-list-item-meta-size: 48px; - } - - mwc-icon-button.hidden { - display: none; - } - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - `; -} diff --git a/packages/plugins/src/editors/subscription/goose/subscriber-list.ts b/packages/plugins/src/editors/subscription/goose/subscriber-list.ts deleted file mode 100644 index 2fdcafd57a..0000000000 --- a/packages/plugins/src/editors/subscription/goose/subscriber-list.ts +++ /dev/null @@ -1,497 +0,0 @@ -import { - css, - customElement, - html, - property, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - identity, -} from '@openscd/open-scd/src/foundation.js'; - -import { - createElement, -} from '@openscd/xml'; - -import { - ComplexAction, - Create, - Delete, - Move, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - GOOSESelectEvent, - GooseSubscriptionEvent, - newGooseSubscriptionEvent, -} from './foundation.js'; -import { emptyInputsDeleteActions } from '@openscd/open-scd/src/foundation/ied.js'; -import { - canCreateValidExtRef, - createExtRefElement, - existExtRef, - getExistingSupervision, - getExtRef, - getFirstSubscribedExtRef, - IEDSelectEvent, - instantiateSubscriptionSupervision, - ListElement, - removeSubscriptionSupervision, - styles, - SubscriberListContainer, - SubscribeStatus, - View, - ViewEvent, -} from '../foundation.js'; - -/** Defining view outside the class, which makes it persistent. */ -let view: View = View.PUBLISHER; - -/** An sub element for subscribing and unsubscribing IEDs to GOOSE messages. */ -@customElement('subscriber-list-goose') -export class SubscriberList extends SubscriberListContainer { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - /** Current selected GOOSE message (when in GOOSE Publisher view) */ - currentSelectedGseControl: Element | undefined; - - /** The name of the IED belonging to the current selected GOOSE */ - currentGooseIedName: string | undefined | null; - - constructor() { - super(); - this.onIEDSelectEvent = this.onIEDSelectEvent.bind(this); - this.onGOOSESelectEvent = this.onGOOSESelectEvent.bind(this); - this.onGooseSubscriptionEvent = this.onGooseSubscriptionEvent.bind(this); - this.onViewChange = this.onViewChange.bind(this); - - const parentDiv = this.closest('.container'); - if (parentDiv) { - parentDiv.addEventListener('ied-select', this.onIEDSelectEvent); - parentDiv.addEventListener('goose-select', this.onGOOSESelectEvent); - parentDiv.addEventListener( - 'goose-subscription', - this.onGooseSubscriptionEvent - ); - parentDiv.addEventListener('view', this.onViewChange); - } - } - - private async onIEDSelectEvent(event: IEDSelectEvent) { - if (!event.detail.ied) return; - this.currentSelectedIed = event.detail.ied!; - - this.resetElements(); - - const subscribedInputs = this.currentSelectedIed.querySelectorAll( - `LN0 > Inputs, LN > Inputs` - ); - - Array.from(this.doc.querySelectorAll('GSEControl')) - .filter(cb => cb.hasAttribute('datSet')) - .forEach(control => { - const ied = control.closest('IED')!; - - if ( - ied.getAttribute('name') == - this.currentSelectedIed?.getAttribute('name') - ) - return; - - /** If no Inputs is available, it's automatically available. */ - if (subscribedInputs.length == 0) { - this.availableElements.push({ element: control }); - return; - } - - let numberOfLinkedExtRefs = 0; - const dataSet = ied.querySelector( - `DataSet[name="${control.getAttribute('datSet')}"]` - ); - - if (!dataSet) return; - - dataSet!.querySelectorAll('FCDA').forEach(fcda => { - subscribedInputs.forEach(inputs => { - if (getExtRef(inputs, fcda, control)) { - numberOfLinkedExtRefs++; - } - }); - }); - - if (numberOfLinkedExtRefs == 0) { - this.availableElements.push({ element: control }); - return; - } - - if (numberOfLinkedExtRefs >= dataSet!.querySelectorAll('FCDA').length) { - this.subscribedElements.push({ element: control }); - } else { - this.availableElements.push({ element: control, partial: true }); - } - }); - - this.requestUpdate(); - } - - private async onGOOSESelectEvent(event: GOOSESelectEvent) { - if (!event.detail.dataset || !event.detail.gseControl) return; - - this.currentSelectedGseControl = event.detail.gseControl; - this.currentUsedDataset = event.detail.dataset; - this.currentGooseIedName = this.currentSelectedGseControl - ?.closest('IED') - ?.getAttribute('name'); - - this.resetElements(); - - Array.from(this.doc.querySelectorAll(':root > IED')) - .filter(ied => ied.getAttribute('name') != this.currentGooseIedName) - .forEach(ied => { - const inputElements = ied.querySelectorAll(`LN0 > Inputs, LN > Inputs`); - - let numberOfLinkedExtRefs = 0; - - /** - * If no Inputs element is found, we can safely say it's not subscribed. - */ - if (!inputElements) { - this.availableElements.push({ element: ied }); - return; - } - - /** - * Count all the linked ExtRefs. - */ - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - inputElements.forEach(inputs => { - if (getExtRef(inputs, fcda, this.currentSelectedGseControl)) { - numberOfLinkedExtRefs++; - } - }); - }); - - /** - * Make a distinction between not subscribed at all, - * partially subscribed and fully subscribed. - */ - if (numberOfLinkedExtRefs == 0) { - this.availableElements.push({ element: ied }); - return; - } - - if ( - numberOfLinkedExtRefs >= - this.currentUsedDataset!.querySelectorAll('FCDA').length - ) { - this.subscribedElements.push({ element: ied }); - } else { - this.availableElements.push({ element: ied, partial: true }); - } - }); - - this.requestUpdate(); - } - - private async onGooseSubscriptionEvent(event: GooseSubscriptionEvent) { - let iedToSubscribe = event.detail.element; - - if (view == View.SUBSCRIBER) { - const dataSetName = event.detail.element.getAttribute('datSet'); - this.currentUsedDataset = - event.detail.element.parentElement?.querySelector( - `DataSet[name="${dataSetName}"]` - ); - this.currentSelectedGseControl = event.detail.element; - this.currentGooseIedName = event.detail.element - .closest('IED') - ?.getAttribute('name'); - iedToSubscribe = this.currentSelectedIed!; - } - - switch (event.detail.subscribeStatus) { - case SubscribeStatus.Full: { - this.unsubscribe(iedToSubscribe); - break; - } - case SubscribeStatus.Partial: { - this.subscribe(iedToSubscribe); - break; - } - case SubscribeStatus.None: { - this.subscribe(iedToSubscribe); - break; - } - } - } - - private async onViewChange(event: ViewEvent) { - view = event.detail.view; - - this.currentSelectedIed = undefined; - this.currentSelectedGseControl = undefined; - - this.resetElements(); - this.requestUpdate(); - } - - private async subscribe(ied: Element): Promise { - if (!ied.querySelector('LN0')) return; - - let inputsElement = ied.querySelector('LN0 > Inputs'); - if (!inputsElement) - inputsElement = createElement(ied.ownerDocument, 'Inputs', {}); - - const complexAction: ComplexAction = { - actions: [], - title: get(`subscription.connect`), - }; - - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - if ( - !existExtRef(inputsElement!, fcda, this.currentSelectedGseControl) && - canCreateValidExtRef(fcda, this.currentSelectedGseControl) - ) { - const extRef = createExtRefElement( - this.currentSelectedGseControl, - fcda - ); - - if (inputsElement?.parentElement) - complexAction.actions.push({ - new: { parent: inputsElement!, element: extRef }, - }); - else inputsElement?.appendChild(extRef); - } - }); - - // we need to extend the actions array with the actions for the instantiation of the LGOS - const supervisionActions = instantiateSubscriptionSupervision( - this.currentSelectedGseControl, - ied - ); - if (inputsElement.parentElement) { - complexAction.actions.concat(supervisionActions); - } else { - /** If the IED doesn't have a Inputs element, just append it to the first LN0 element. */ - const inputAction: (Create | Move)[] = [ - { - new: { parent: ied.querySelector('LN0')!, element: inputsElement }, - }, - ]; - complexAction.actions = inputAction.concat(supervisionActions); - } - this.dispatchEvent(newActionEvent(complexAction)); - } - - private async unsubscribe(ied: Element): Promise { - const actions: Delete[] = []; - ied.querySelectorAll('LN0 > Inputs, LN > Inputs').forEach(inputs => { - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - const extRef = getExtRef(inputs, fcda, this.currentSelectedGseControl); - if (extRef) actions.push({ old: { parent: inputs, element: extRef } }); - }); - }); - - // Check if empty Input Element should also be removed. - actions.push(...emptyInputsDeleteActions(actions)); - - // we need to extend the actions array with the actions for removing the supervision - actions.push( - ...removeSubscriptionSupervision(this.currentSelectedGseControl, ied) - ); - - this.dispatchEvent( - newActionEvent({ - title: get('subscription.disconnect'), - actions: actions, - }) - ); - } - - renderSubscriber(status: SubscribeStatus, element: Element): TemplateResult { - let firstSubscribedExtRef: Element | null = null; - let supervisionNode: Element | null = null; - if (status !== SubscribeStatus.None) { - if (view === View.PUBLISHER) { - firstSubscribedExtRef = getFirstSubscribedExtRef( - this.currentSelectedGseControl!, - element - ); - supervisionNode = getExistingSupervision(firstSubscribedExtRef!); - } else { - firstSubscribedExtRef = getFirstSubscribedExtRef( - element, - this.currentSelectedIed! - ); - supervisionNode = getExistingSupervision(firstSubscribedExtRef!); - } - } - return html` { - this.dispatchEvent( - newGooseSubscriptionEvent(element, status ?? SubscribeStatus.None) - ); - }} - graphic="avatar" - ?hasMeta=${supervisionNode !== null} - > - ${view == View.PUBLISHER - ? element.getAttribute('name') - : element.getAttribute('name') + - ` (${element.closest('IED')?.getAttribute('name')})`} - ${status == SubscribeStatus.Full ? html`clear` : html`add`} - ${supervisionNode !== null - ? html`monitor_heart` - : nothing} - `; - } - - renderUnSubscribers(elements: ListElement[]): TemplateResult { - return html` - ${get('subscription.subscriber.availableToSubscribe')} - -
  • - ${elements.length > 0 - ? elements.map(element => - this.renderSubscriber(SubscribeStatus.None, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderPartiallySubscribers(elements: ListElement[]): TemplateResult { - return html` - ${get('subscription.subscriber.partiallySubscribed')} - -
  • - ${elements.length > 0 - ? elements.map(element => - this.renderSubscriber(SubscribeStatus.Partial, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderFullSubscribers(): TemplateResult { - return html` - ${get('subscription.subscriber.subscribed')} - -
  • - ${this.subscribedElements.length > 0 - ? this.subscribedElements.map(element => - this.renderSubscriber(SubscribeStatus.Full, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderTitle(): TemplateResult { - const gseControlName = - this.currentSelectedGseControl?.getAttribute('name') ?? undefined; - - return view == View.PUBLISHER - ? html`

    - ${get('subscription.goose.publisher.subscriberTitle', { - selected: gseControlName - ? this.currentGooseIedName + ' > ' + gseControlName - : 'GOOSE', - })} -

    ` - : html`

    - ${get('subscription.goose.subscriber.publisherTitle', { - selected: this.currentSelectedIed - ? this.currentSelectedIed.getAttribute('name')! - : 'IED', - })} -

    `; - } - - protected firstUpdated(): void { - this.currentSelectedIed = undefined; - } - - render(): TemplateResult { - return html` -
    - ${this.renderTitle()} - ${this.availableElements.length != 0 || - this.subscribedElements.length != 0 - ? html`
    - - ${this.renderFullSubscribers()} - ${this.renderPartiallySubscribers( - this.availableElements.filter(element => element.partial) - )} - ${this.renderUnSubscribers( - this.availableElements.filter(element => !element.partial) - )} - -
    ` - : html` - - ${ - view == View.PUBLISHER - ? get('subscription.subscriber.noControlBlockSelected') - : get('subscription.subscriber.noIedSelected') - } - - - `} -
    - `; - } - - static styles = css` - ${styles} - - .wrapper { - height: 100vh; - overflow-y: scroll; - } - `; -} diff --git a/packages/plugins/src/editors/subscription/ied-list.ts b/packages/plugins/src/editors/subscription/ied-list.ts deleted file mode 100644 index eac128d1e1..0000000000 --- a/packages/plugins/src/editors/subscription/ied-list.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon'; -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { getNameAttribute } from '@openscd/open-scd/src/foundation.js'; -import { getOrderedIeds, newIEDSelectEvent, styles } from './foundation.js'; - -let selectedIed: Element | undefined; - -function onOpenDocResetSelectedGooseMsg() { - selectedIed = undefined; -} -addEventListener('open-doc', onOpenDocResetSelectedGooseMsg); - -@customElement('ied-list') -export class IedList extends LitElement { - @property() - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @property({ type: String }) - serviceType?: 'goose' | 'smv'; - - private onIedSelect(element: Element): void { - selectedIed = element; - - this.dispatchEvent(newIEDSelectEvent(selectedIed)); - } - - protected updated(): void { - this.dispatchEvent(newIEDSelectEvent(selectedIed)); - } - - protected firstUpdated(): void { - selectedIed = undefined; - } - - render(): TemplateResult { - return html`
    -

    - ${get(`subscription.${this.serviceType}.subscriber.iedListTitle`)} -

    - - ${getOrderedIeds(this.doc).map( - ied => - html` - this.onIedSelect(ied)} - graphic="icon" - > - ${getNameAttribute(ied)} - developer_board - - ` - )} - -
    `; - } - - static styles = css` - ${styles} - `; -} diff --git a/packages/plugins/src/editors/subscription/later-binding/ext-ref-later-binding-list.ts b/packages/plugins/src/editors/subscription/later-binding/ext-ref-later-binding-list.ts deleted file mode 100644 index 1ab1218d6b..0000000000 --- a/packages/plugins/src/editors/subscription/later-binding/ext-ref-later-binding-list.ts +++ /dev/null @@ -1,388 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - state, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import { - getDescriptionAttribute, - identity, -} from '@openscd/open-scd/src/foundation.js'; - -import { - cloneElement, -} from '@openscd/xml'; - -import { - ComplexAction, - Delete, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; - -import { - getExistingSupervision, - styles, - updateExtRefElement, - serviceTypes, - instantiateSubscriptionSupervision, - removeSubscriptionSupervision, - FcdaSelectEvent, - newSubscriptionChangedEvent, - canRemoveSubscriptionSupervision, -} from '../foundation.js'; - -import { - getExtRefElements, - getSubscribedExtRefElements, - fcdaSpecification, - inputRestriction, - isSubscribed, -} from './foundation.js'; - -/** - * A sub element for showing all Ext Refs from a FCDA Element. - * The List reacts on a custom event to know which FCDA Element was selected and updated the view. - */ -@customElement('extref-later-binding-list') -export class ExtRefLaterBindingList extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property() - controlTag!: 'SampledValueControl' | 'GSEControl'; - - @state() - currentSelectedControlElement: Element | undefined; - @state() - currentSelectedFcdaElement: Element | undefined; - @state() - currentIedElement: Element | undefined; - - serviceTypeLookup = { - GSEControl: 'GOOSE', - SampledValueControl: 'SMV', - }; - - constructor() { - super(); - - const parentDiv = this.closest('.container'); - if (parentDiv) { - this.onFcdaSelectEvent = this.onFcdaSelectEvent.bind(this); - parentDiv.addEventListener('fcda-select', this.onFcdaSelectEvent); - } - } - - private async onFcdaSelectEvent(event: FcdaSelectEvent) { - this.currentSelectedControlElement = event.detail.control; - this.currentSelectedFcdaElement = event.detail.fcda; - - // Retrieve the IED Element to which the FCDA belongs. - // These ExtRef Elements will be excluded. - this.currentIedElement = this.currentSelectedFcdaElement - ? this.currentSelectedFcdaElement.closest('IED') ?? undefined - : undefined; - } - - /** - * Check data consistency of source `FCDA` and sink `ExtRef` based on - * `ExtRef`'s `pLN`, `pDO`, `pDA` and `pServT` attributes. - * Consistent means `CDC` and `bType` of both ExtRef and FCDA is equal. - * In case - * - `pLN`, `pDO`, `pDA` or `pServT` attributes are not present, allow subscribing - * - no CDC or bType can be extracted, do not allow subscribing - * - * @param extRef - The `ExtRef` Element to check against - */ - private unsupportedExtRefElement(extRef: Element): boolean { - // Vendor does not provide data for the check - if ( - !extRef.hasAttribute('pLN') || - !extRef.hasAttribute('pDO') || - !extRef.hasAttribute('pDA') || - !extRef.hasAttribute('pServT') - ) - return false; - - // Not ready for any kind of subscription - if (!this.currentSelectedFcdaElement) return true; - - const fcda = fcdaSpecification(this.currentSelectedFcdaElement); - const input = inputRestriction(extRef); - - if (fcda.cdc === null && input.cdc === null) return true; - if (fcda.bType === null && input.bType === null) return true; - if ( - serviceTypes[this.currentSelectedControlElement?.tagName ?? ''] !== - extRef.getAttribute('pServT') - ) - return true; - - return fcda.cdc !== input.cdc || fcda.bType !== input.bType; - } - - /** - * Unsubscribing means removing a list of attributes from the ExtRef Element. - * - * @param extRefElement - The Ext Ref Element to clean from attributes. - */ - private unsubscribe(extRefElement: Element): void { - if ( - !this.currentIedElement || - !this.currentSelectedFcdaElement || - !this.currentSelectedControlElement! - ) { - return; - } - const clonedExtRefElement = cloneElement(extRefElement, { - iedName: null, - ldInst: null, - prefix: null, - lnClass: null, - lnInst: null, - doName: null, - daName: null, - serviceType: null, - srcLDInst: null, - srcPrefix: null, - srcLNClass: null, - srcLNInst: null, - srcCBName: null, - }); - - const replaceAction = { - old: { element: extRefElement }, - new: { element: clonedExtRefElement }, - }; - - const subscriberIed = extRefElement.closest('IED') || undefined; - const removeSubscriptionActions: Delete[] = []; - if (canRemoveSubscriptionSupervision(extRefElement)) - removeSubscriptionActions.push( - ...removeSubscriptionSupervision( - this.currentSelectedControlElement, - subscriberIed - ) - ); - - this.dispatchEvent( - newActionEvent({ - title: get(`subscription.disconnect`), - actions: [replaceAction, ...removeSubscriptionActions], - }) - ); - this.dispatchEvent( - newSubscriptionChangedEvent( - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ) - ); - } - - /** - * Subscribing means copying a list of attributes from the FCDA Element (and others) to the ExtRef Element. - * - * @param extRefElement - The Ext Ref Element to add the attributes to. - */ - private subscribe(extRefElement: Element): void { - if ( - !this.currentIedElement || - !this.currentSelectedFcdaElement || - !this.currentSelectedControlElement! - ) { - return; - } - - const complexAction: ComplexAction = { - actions: [], - title: get(`subscription.connect`), - }; - - const replaceAction = { - old: { element: extRefElement }, - new: { - element: updateExtRefElement( - extRefElement, - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ), - }, - }; - complexAction.actions.push(replaceAction); - - const subscriberIed = extRefElement.closest('IED') || undefined; - - complexAction.actions.push( - ...instantiateSubscriptionSupervision( - this.currentSelectedControlElement, - subscriberIed - ) - ); - - this.dispatchEvent(newActionEvent(complexAction)); - this.dispatchEvent( - newSubscriptionChangedEvent( - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ) - ); - } - - private getSubscribedExtRefElements(): Element[] { - return getSubscribedExtRefElements( - this.doc.getRootNode(), - this.controlTag, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement, - true - ); - } - - private getAvailableExtRefElements(): Element[] { - return getExtRefElements( - this.doc.getRootNode(), - this.currentSelectedFcdaElement, - true - ).filter( - extRefElement => - !isSubscribed(extRefElement) && - (!extRefElement.hasAttribute('serviceType') || - extRefElement.getAttribute('serviceType') === - this.serviceTypeLookup[this.controlTag]) - ); - } - - private renderTitle(): TemplateResult { - return html`

    ${get(`subscription.laterBinding.extRefList.title`)}

    `; - } - - private renderExtRefElement(extRefElement: Element): TemplateResult { - const supervisionNode = getExistingSupervision(extRefElement); - return html` this.unsubscribe(extRefElement)} - value="${identity(extRefElement)}" - > - - ${extRefElement.getAttribute('intAddr')} - ${getDescriptionAttribute(extRefElement) - ? html` (${getDescriptionAttribute(extRefElement)})` - : nothing} - - ${identity(extRefElement.parentElement)}${supervisionNode !== null - ? ` (${identity(supervisionNode)})` - : ''} - swap_horiz - ${supervisionNode !== null - ? html`monitor_heart` - : nothing} - `; - } - - private renderSubscribedExtRefs(): TemplateResult { - const subscribedExtRefs = this.getSubscribedExtRefElements(); - return html` - - ${get('subscription.subscriber.subscribed')} - -
  • - ${subscribedExtRefs.length > 0 - ? html`${subscribedExtRefs.map(extRefElement => - this.renderExtRefElement(extRefElement) - )}` - : html` - ${get('subscription.laterBinding.extRefList.noSubscribedExtRefs')} - `} - `; - } - - private renderAvailableExtRefs(): TemplateResult { - const availableExtRefs = this.getAvailableExtRefElements(); - return html` - - ${get('subscription.subscriber.availableToSubscribe')} - -
  • - ${availableExtRefs.length > 0 - ? html`${availableExtRefs.map( - extRefElement => html` this.subscribe(extRefElement)} - value="${identity(extRefElement)}" - > - - ${extRefElement.getAttribute('intAddr')} - ${getDescriptionAttribute(extRefElement) - ? html` (${getDescriptionAttribute(extRefElement)})` - : nothing} - - ${identity(extRefElement.parentElement)} - arrow_back - ` - )}` - : html` - ${get('subscription.laterBinding.extRefList.noAvailableExtRefs')} - `} - `; - } - - render(): TemplateResult { - return html`
    - ${this.currentSelectedControlElement && this.currentSelectedFcdaElement - ? html` - ${this.renderTitle()} - - ${this.renderSubscribedExtRefs()} ${this.renderAvailableExtRefs()} - - ` - : html` -

    ${get('subscription.laterBinding.extRefList.noSelection')}

    - `} -
    `; - } - - static styles = css` - ${styles} - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - `; -} diff --git a/packages/plugins/src/editors/subscription/later-binding/ext-ref-ln-binding-list.ts b/packages/plugins/src/editors/subscription/later-binding/ext-ref-ln-binding-list.ts deleted file mode 100644 index 326a80de5b..0000000000 --- a/packages/plugins/src/editors/subscription/later-binding/ext-ref-ln-binding-list.ts +++ /dev/null @@ -1,377 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - state, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import { - identity, -} from '@openscd/open-scd/src/foundation.js'; - -import { - createElement, -} from '@openscd/xml'; - -import { - ComplexAction, - Delete, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { Nsdoc } from '@openscd/open-scd/src/foundation/nsdoc.js'; - -import { - canCreateValidExtRef, - createExtRefElement, - existExtRef, - FcdaSelectEvent, - getExtRef, - getExistingSupervision, - newSubscriptionChangedEvent, - removeSubscriptionSupervision, - instantiateSubscriptionSupervision, - styles, - canRemoveSubscriptionSupervision, -} from '../foundation.js'; -import { getSubscribedExtRefElements } from './foundation.js'; -import { emptyInputsDeleteActions } from '@openscd/open-scd/src/foundation/ied.js'; - -/** - * A sub element for showing all Ext Refs from a FCDA Element. - * The List reacts on a custom event to know which FCDA Element was selected and updated the view. - */ -@customElement('extref-ln-binding-list') -export class ExtRefLnBindingList extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property() - nsdoc!: Nsdoc; - @property() - controlTag!: 'SampledValueControl' | 'GSEControl'; - - @state() - currentSelectedControlElement: Element | undefined; - @state() - currentSelectedFcdaElement: Element | undefined; - @state() - currentIedElement: Element | undefined; - - constructor() { - super(); - - const parentDiv = this.closest('.container'); - if (parentDiv) { - this.onFcdaSelectEvent = this.onFcdaSelectEvent.bind(this); - parentDiv.addEventListener('fcda-select', this.onFcdaSelectEvent); - } - } - - private getLNElements(): Element[] { - if (this.doc) { - return Array.from( - this.doc.querySelectorAll('LDevice > LN0, LDevice > LN') - ).filter(element => element.closest('IED') !== this.currentIedElement); - } - return []; - } - - private getSubscribedLNElements(): Element[] { - return this.getLNElements().filter( - element => - getSubscribedExtRefElements( - element, - this.controlTag, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement, - false - ).length > 0 - ); - } - - private getAvailableLNElements(): Element[] { - return this.getLNElements().filter( - element => - getSubscribedExtRefElements( - element, - this.controlTag, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement, - false - ).length == 0 - ); - } - - private async onFcdaSelectEvent(event: FcdaSelectEvent) { - this.currentSelectedControlElement = event.detail.control; - this.currentSelectedFcdaElement = event.detail.fcda; - - // Retrieve the IED Element to which the FCDA belongs. - // These LN Elements will be excluded. - this.currentIedElement = this.currentSelectedFcdaElement - ? this.currentSelectedFcdaElement.closest('IED') ?? undefined - : undefined; - } - - private subscribe(lnElement: Element): ComplexAction | null { - if ( - !this.currentIedElement || - !this.currentSelectedFcdaElement || - !this.currentSelectedControlElement! - ) { - return null; - } - - const complexAction: ComplexAction = { - actions: [], - title: get(`subscription.connect`), - }; - - let inputsElement = lnElement.querySelector(':scope > Inputs'); - if (!inputsElement) { - inputsElement = createElement(lnElement.ownerDocument, 'Inputs', {}); - complexAction.actions.push({ - new: { parent: lnElement, element: inputsElement }, - }); - } - - if ( - !existExtRef( - inputsElement!, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement - ) && - canCreateValidExtRef( - this.currentSelectedFcdaElement, - this.currentSelectedControlElement - ) - ) { - const extRef = createExtRefElement( - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ); - complexAction.actions.push({ - new: { parent: inputsElement, element: extRef }, - }); - } - - // we need to extend the actions array with the actions for the instation of the LGOS - const subscriberIed = lnElement.closest('IED') || undefined; - complexAction.actions.push( - ...instantiateSubscriptionSupervision( - this.currentSelectedControlElement, - subscriberIed - ) - ); - - return complexAction; - } - - private unsubscribe(lnElement: Element): ComplexAction | null { - if ( - !this.currentIedElement || - !this.currentSelectedFcdaElement || - !this.currentSelectedControlElement! - ) { - return null; - } - - const actions: Delete[] = []; - const inputElement = lnElement.querySelector(':scope > Inputs')!; - const extRefElement = getExtRef( - inputElement, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement - ); - if (extRefElement) { - actions.push({ old: { parent: inputElement, element: extRefElement } }); - } - - // Check if empty Input Element should also be removed. - actions.push(...emptyInputsDeleteActions(actions)); - - // we need to extend the actions array with the actions for removing the supervision - const subscriberIed = lnElement.closest('IED') || undefined; - if (extRefElement && canRemoveSubscriptionSupervision(extRefElement)) - actions.push( - ...removeSubscriptionSupervision( - this.currentSelectedControlElement, - subscriberIed - ) - ); - - return { - title: get('subscription.disconnect'), - actions: actions, - }; - } - - private bindingNotSupported(lnElement: Element): boolean { - const iedElement = lnElement.closest('IED')!; - return ( - (iedElement - .querySelector( - ':scope > AccessPoint > Services > ClientServices, :scope > Services > ClientServices' - ) - ?.getAttribute('noIctBinding') ?? 'false') === 'true' - ); - } - - private buildLNTitle(lnElement: Element): string { - const prefix = lnElement.getAttribute('prefix'); - const inst = lnElement.getAttribute('inst'); - - const data = this.nsdoc.getDataDescription(lnElement); - - return `${prefix ? `${prefix} - ` : ''}${data.label} ${ - inst ? ` - ${inst}` : '' - }`; - } - - private renderTitle(): TemplateResult { - return html`

    ${get(`subscription.binding.extRefList.title`)}

    `; - } - - private renderSubscribedLN(lnElement: Element): TemplateResult { - const extRefs = getSubscribedExtRefElements( - lnElement, - this.controlTag, - this.currentSelectedFcdaElement, - this.currentSelectedControlElement, - false - ); - const supervisionNode = getExistingSupervision(extRefs[0]); - return html` { - const replaceAction = this.unsubscribe(lnElement); - if (replaceAction) { - this.dispatchEvent(newActionEvent(replaceAction)); - this.dispatchEvent( - newSubscriptionChangedEvent( - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ) - ); - } - }} - > - ${this.buildLNTitle(lnElement)} - ${identity(lnElement.closest('LDevice'))} - close - ${supervisionNode !== null - ? html`monitor_heart` - : nothing}`; - } - - private renderSubscribedLNs(): TemplateResult { - const subscribedLNs = this.getSubscribedLNElements(); - return html` - - ${get('subscription.subscriber.subscribed')} - -
  • - ${subscribedLNs.length > 0 - ? html`${subscribedLNs.map(lN => this.renderSubscribedLN(lN))}` - : html` - ${get('subscription.binding.extRefList.noSubscribedLNs')} - `} - `; - } - - private renderAvailableLNs(): TemplateResult { - const availableLNs = this.getAvailableLNElements(); - return html` - - ${get('subscription.subscriber.availableToSubscribe')} - -
  • - ${availableLNs.length > 0 - ? html`${availableLNs.map( - lnElement => html` { - const replaceAction = this.subscribe(lnElement); - if (replaceAction) { - this.dispatchEvent(newActionEvent(replaceAction)); - this.dispatchEvent( - newSubscriptionChangedEvent( - this.currentSelectedControlElement, - this.currentSelectedFcdaElement - ) - ); - } - }} - > - ${this.buildLNTitle(lnElement)} - - ${identity(lnElement.closest('LDevice'))} - - add - ` - )}` - : html` - ${get('subscription.binding.extRefList.noAvailableLNs')} - `} - `; - } - - render(): TemplateResult { - return html`
    - ${this.currentSelectedControlElement && this.currentSelectedFcdaElement - ? html` - ${this.renderTitle()} - - ${this.renderSubscribedLNs()} ${this.renderAvailableLNs()} - - ` - : html` -

    ${get('subscription.binding.extRefList.noSelection')}

    - `} -
    `; - } - - static styles = css` - ${styles} - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - `; -} diff --git a/packages/plugins/src/editors/subscription/later-binding/foundation.ts b/packages/plugins/src/editors/subscription/later-binding/foundation.ts deleted file mode 100644 index d9fef817fd..0000000000 --- a/packages/plugins/src/editors/subscription/later-binding/foundation.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { getSclSchemaVersion } from '@openscd/open-scd/src/foundation.js'; -import { serviceTypes } from '../foundation.js'; - -function dataAttributeSpecification( - anyLn: Element, - doName: string, - daName: string -): { cdc: string | null; bType: string | null } { - const doc = anyLn.ownerDocument; - const lNodeType = doc.querySelector( - `LNodeType[id="${anyLn.getAttribute('lnType')}"]` - ); - - const doNames = doName.split('.'); - let leaf: Element | null | undefined = lNodeType; - for (const doName of doNames) { - const dO: Element | null | undefined = leaf?.querySelector( - `DO[name="${doName}"], SDO[name="${doName}"]` - ); - leaf = doc.querySelector(`DOType[id="${dO?.getAttribute('type')}"]`); - } - if (!leaf || !leaf.getAttribute('cdc')) return { cdc: null, bType: null }; - - const cdc = leaf.getAttribute('cdc')!; - - const daNames = daName.split('.'); - for (const daName of daNames) { - const dA: Element | null | undefined = leaf?.querySelector( - `DA[name="${daName}"], BDA[name="${daName}"]` - ); - leaf = - daNames.indexOf(daName) < daNames.length - 1 - ? doc.querySelector(`DAType[id="${dA?.getAttribute('type')}"]`) - : dA; - } - if (!leaf || !leaf.getAttribute('bType')) return { cdc, bType: null }; - - const bType = leaf.getAttribute('bType')!; - - return { bType, cdc }; -} - -/** - * @param fcda - Data attribute reference in a data set - * @returns Data objects `CDC` and data attributes `bType` - */ -export function fcdaSpecification(fcda: Element): { - cdc: string | null; - bType: string | null; -} { - const [doName, daName] = ['doName', 'daName'].map(attr => - fcda.getAttribute(attr) - ); - if (!doName || !daName) return { cdc: null, bType: null }; - - const ied = fcda.closest('IED'); - - const anyLn = Array.from( - ied?.querySelectorAll( - `LDevice[inst="${fcda.getAttribute( - 'ldInst' - )}"] > LN, LDevice[inst="${fcda.getAttribute('inst')}"] LN0` - ) ?? [] - ).find(anyLn => { - return ( - (anyLn.getAttribute('prefix') ?? '') === - (fcda.getAttribute('prefix') ?? '') && - (anyLn.getAttribute('lnClass') ?? '') === - (fcda.getAttribute('lnClass') ?? '') && - (anyLn.getAttribute('inst') ?? '') === (fcda.getAttribute('lnInst') ?? '') - ); - }); - if (!anyLn) return { cdc: null, bType: null }; - - return dataAttributeSpecification(anyLn, doName, daName); -} - -/** - * Edition 2 and later SCL files allow to restrict subscription on - * later binding type inputs (`ExtRef` elements) based on a `CDC` and - * basic type `bType`. - * @param extRef - A later binding type input in the sink IED - * @returns data objects `CDC` and data attribute basic type `bType` or `null` - */ -export function inputRestriction(extRef: Element): { - cdc: string | null; - bType: string | null; -} { - const [pLN, pDO, pDA] = ['pLN', 'pDO', 'pDA'].map(attr => - extRef.getAttribute(attr) - ); - if (!pLN || !pDO || !pDA) return { cdc: null, bType: null }; - - const anyLns = Array.from( - extRef - .closest('IED') - ?.querySelectorAll(`LN[lnClass="${pLN}"],LN0[lnClass="${pLN}"]`) ?? [] - ); - - for (const anyLn of anyLns) { - const dataSpec = dataAttributeSpecification(anyLn, pDO, pDA); - if (dataSpec.cdc !== null && dataSpec.bType !== null) return dataSpec; - } - - return { cdc: null, bType: null }; -} - -/** - * Simple function to check if the attribute of the Left Side has the same value as the attribute of the Right Element. - * - * @param leftElement - The Left Element to check against. - * @param rightElement - The Right Element to check. - * @param attributeName - The name of the attribute to check. - */ -export function sameAttributeValue( - leftElement: Element | undefined, - rightElement: Element | undefined, - attributeName: string -): boolean { - return ( - (leftElement?.getAttribute(attributeName) ?? '') === - (rightElement?.getAttribute(attributeName) ?? '') - ); -} - -/** - * Simple function to check if the attribute of the Left Side has the same value as the attribute of the Right Element. - * - * @param leftElement - The Left Element to check against. - * @param leftAttributeName - The name of the attribute (left) to check against. - * @param rightElement - The Right Element to check. - * @param rightAttributeName - The name of the attribute (right) to check. - */ -export function sameAttributeValueDiffName( - leftElement: Element | undefined, - leftAttributeName: string, - rightElement: Element | undefined, - rightAttributeName: string -): boolean { - return ( - (leftElement?.getAttribute(leftAttributeName) ?? '') === - (rightElement?.getAttribute(rightAttributeName) ?? '') - ); -} - -/** - * If needed check version specific attributes against FCDA Element. - * - * @param controlTag - Indicates which type of control element. - * @param controlElement - The Control Element to check against. - * @param extRefElement - The Ext Ref Element to check. - */ -function checkEditionSpecificRequirements( - controlTag: 'SampledValueControl' | 'GSEControl', - controlElement: Element | undefined, - extRefElement: Element -): boolean { - // For 2003 Edition no extra check needed. - if (getSclSchemaVersion(extRefElement.ownerDocument) === '2003') { - return true; - } - - const lDeviceElement = controlElement?.closest('LDevice') ?? undefined; - const lnElement = controlElement?.closest('LN0') ?? undefined; - - // If ExtRef is missing 'srcLNClass', it defaults to 'LLN0' as specified in the standard - const extRefIsMissingSrcLNClass = !extRefElement.hasAttribute('srcLNClass'); - const isLnClassLLN0 = lnElement?.getAttribute('lnClass') === 'LLN0'; - const canIgnoreSrcLNClass = isLnClassLLN0 && extRefIsMissingSrcLNClass; - - // For the 2007B and 2007B4 Edition we need to check some extra attributes. - return ( - (extRefElement.getAttribute('serviceType') ?? '') === - serviceTypes[controlTag] && - sameAttributeValueDiffName( - extRefElement, - 'srcLDInst', - lDeviceElement, - 'inst' - ) && - sameAttributeValueDiffName( - extRefElement, - 'scrPrefix', - lnElement, - 'prefix' - ) && - (canIgnoreSrcLNClass || sameAttributeValueDiffName( - extRefElement, - 'srcLNClass', - lnElement, - 'lnClass' - )) && - sameAttributeValueDiffName(extRefElement, 'srcLNInst', lnElement, 'inst') && - sameAttributeValueDiffName( - extRefElement, - 'srcCBName', - controlElement, - 'name' - ) - ); -} - -/** - * Check if specific attributes from the ExtRef Element are the same as the ones from the FCDA Element - * and also if the IED Name is the same. If that is the case this ExtRef subscribes to the selected FCDA - * Element. - * - * @param controlTag - Indicates which type of control element. - * @param controlElement - The Control Element to check against. - * @param fcdaElement - The FCDA Element to check against. - * @param extRefElement - The Ext Ref Element to check. - */ -export function isSubscribedTo( - controlTag: 'SampledValueControl' | 'GSEControl', - controlElement: Element | undefined, - fcdaElement: Element | undefined, - extRefElement: Element -): boolean { - return ( - extRefElement.getAttribute('iedName') === - fcdaElement?.closest('IED')?.getAttribute('name') && - sameAttributeValue(fcdaElement, extRefElement, 'ldInst') && - sameAttributeValue(fcdaElement, extRefElement, 'prefix') && - sameAttributeValue(fcdaElement, extRefElement, 'lnClass') && - sameAttributeValue(fcdaElement, extRefElement, 'lnInst') && - sameAttributeValue(fcdaElement, extRefElement, 'doName') && - sameAttributeValue(fcdaElement, extRefElement, 'daName') && - checkEditionSpecificRequirements(controlTag, controlElement, extRefElement) - ); -} - -/** - * Check if the ExtRef is already subscribed to a FCDA Element. - * - * @param extRefElement - The Ext Ref Element to check. - */ -export function isSubscribed(extRefElement: Element): boolean { - return ( - extRefElement.hasAttribute('iedName') && - extRefElement.hasAttribute('ldInst') && - extRefElement.hasAttribute('prefix') && - extRefElement.hasAttribute('lnClass') && - extRefElement.hasAttribute('lnInst') && - extRefElement.hasAttribute('doName') && - extRefElement.hasAttribute('daName') - ); -} - -export function getExtRefElements( - rootElement: Element, - fcdaElement: Element | undefined, - includeLaterBinding: boolean -): Element[] { - return Array.from(rootElement.querySelectorAll('ExtRef')) - .filter( - element => - (includeLaterBinding && element.hasAttribute('intAddr')) || - (!includeLaterBinding && !element.hasAttribute('intAddr')) - ) - .filter(element => element.closest('IED') !== fcdaElement?.closest('IED')); -} - -export function getSubscribedExtRefElements( - rootElement: Element, - controlTag: 'SampledValueControl' | 'GSEControl', - fcdaElement: Element | undefined, - controlElement: Element | undefined, - includeLaterBinding: boolean -): Element[] { - return getExtRefElements( - rootElement, - fcdaElement, - includeLaterBinding - ).filter(extRefElement => - isSubscribedTo(controlTag, controlElement, fcdaElement, extRefElement) - ); -} diff --git a/packages/plugins/src/editors/subscription/sampledvalues/foundation.ts b/packages/plugins/src/editors/subscription/sampledvalues/foundation.ts deleted file mode 100644 index 8566b80c63..0000000000 --- a/packages/plugins/src/editors/subscription/sampledvalues/foundation.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { SubscribeStatus } from '../foundation.js'; - -export interface SmvSelectDetail { - smvControl: Element | undefined; - dataset: Element | undefined; -} -export type SmvSelectEvent = CustomEvent; -export function newSmvSelectEvent( - smvControl: Element | undefined, - dataset: Element | undefined, - eventInitDict?: CustomEventInit -): SmvSelectEvent { - return new CustomEvent('smv-select', { - bubbles: true, - composed: true, - ...eventInitDict, - detail: { smvControl: smvControl, dataset, ...eventInitDict?.detail }, - }); -} - -export interface SmvSubscriptionDetail { - element: Element; - subscribeStatus: SubscribeStatus; -} -export type SmvSubscriptionEvent = CustomEvent; -export function newSmvSubscriptionEvent( - element: Element, - subscribeStatus: SubscribeStatus -): SmvSubscriptionEvent { - return new CustomEvent('smv-subscription', { - bubbles: true, - composed: true, - detail: { element, subscribeStatus }, - }); -} - -declare global { - interface ElementEventMap { - ['smv-select']: SmvSelectEvent; - ['smv-subscription']: SmvSubscriptionEvent; - } -} diff --git a/packages/plugins/src/editors/subscription/sampledvalues/smv-list.ts b/packages/plugins/src/editors/subscription/sampledvalues/smv-list.ts deleted file mode 100644 index 63a40c4c41..0000000000 --- a/packages/plugins/src/editors/subscription/sampledvalues/smv-list.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; - -import { - getNameAttribute, - identity, - newWizardEvent, -} from '@openscd/open-scd/src/foundation.js'; -import { newSmvSelectEvent } from './foundation.js'; -import { smvIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { getOrderedIeds, styles } from '../foundation.js'; -import { classMap } from 'lit-html/directives/class-map.js'; -import { wizards } from '../../../wizards/wizard-library.js'; - -let selectedSmvMsg: Element | undefined; -let selectedDataSet: Element | undefined | null; - -function onOpenDocResetSelectedSmvMsg() { - selectedSmvMsg = undefined; - selectedDataSet = undefined; -} -addEventListener('open-doc', onOpenDocResetSelectedSmvMsg); - -/** An sub element for showing all Sampled Values per IED. */ -@customElement('smv-list') -export class SmvPublisherList extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - private onSelect(smvControl: Element) { - const ln = smvControl.parentElement; - const dataset = ln?.querySelector( - `DataSet[name=${smvControl.getAttribute('datSet')}]` - ); - - selectedSmvMsg = smvControl; - selectedDataSet = dataset; - - this.dispatchEvent(newSmvSelectEvent(selectedSmvMsg, selectedDataSet!)); - - this.requestUpdate(); - } - - private openEditWizard(smvControl: Element): void { - const wizard = wizards['SampledValueControl'].edit(smvControl); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - protected updated(): void { - this.dispatchEvent( - newSmvSelectEvent(selectedSmvMsg, selectedDataSet ?? undefined) - ); - } - - protected firstUpdated(): void { - selectedSmvMsg = undefined; - selectedDataSet = undefined; - } - - renderSmv(smvControl: Element): TemplateResult { - return html` this.onSelect(smvControl)} - graphic="large" - hasMeta - value="${identity(smvControl)}" - > - ${smvIcon} - ${smvControl.getAttribute('name')} - this.openEditWizard(smvControl)} - > - `; - } - - render(): TemplateResult { - return html`
    -

    ${get('subscription.smv.publisher.title')}

    - - ${getOrderedIeds(this.doc).map( - ied => - html` - - ${getNameAttribute(ied)} - developer_board - -
  • - ${Array.from( - ied.querySelectorAll( - ':scope > AccessPoint > Server > LDevice > LN0 > SampledValueControl' - ) - ) - .filter(cb => cb.hasAttribute('datSet')) - .map(control => this.renderSmv(control))} - ` - )} -
    -
    `; - } - - static styles = css` - ${styles} - - mwc-list-item { - --mdc-list-item-meta-size: 48px; - } - - mwc-icon-button.hidden { - display: none; - } - - mwc-list-item.hidden[noninteractive] + li[divider] { - display: none; - } - `; -} diff --git a/packages/plugins/src/editors/subscription/sampledvalues/subscriber-list.ts b/packages/plugins/src/editors/subscription/sampledvalues/subscriber-list.ts deleted file mode 100644 index a2e8edf918..0000000000 --- a/packages/plugins/src/editors/subscription/sampledvalues/subscriber-list.ts +++ /dev/null @@ -1,500 +0,0 @@ -import { - css, - customElement, - html, - property, - TemplateResult, -} from 'lit-element'; -import { nothing } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - identity, -} from '@openscd/open-scd/src/foundation.js'; - -import { - createElement, -} from '@openscd/xml'; - -import { - Create, - ComplexAction, - Delete, - Move, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - newSmvSubscriptionEvent, - SmvSelectEvent, - SmvSubscriptionEvent, -} from './foundation.js'; -import { emptyInputsDeleteActions } from '@openscd/open-scd/src/foundation/ied.js'; -import { - canCreateValidExtRef, - createExtRefElement, - existExtRef, - getExistingSupervision, - getExtRef, - getFirstSubscribedExtRef, - IEDSelectEvent, - instantiateSubscriptionSupervision, - ListElement, - removeSubscriptionSupervision, - styles, - SubscriberListContainer, - SubscribeStatus, - View, - ViewEvent, -} from '../foundation.js'; - -/** Defining view outside the class, which makes it persistent. */ -let view: View = View.PUBLISHER; - -/** An sub element for subscribing and unsubscribing IEDs to Sampled Values messages. */ -@customElement('subscriber-list-smv') -export class SubscriberList extends SubscriberListContainer { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - /** Current selected Sampled Values element (when in GOOSE Publisher view) */ - currentSelectedSmvControl: Element | undefined; - - /** The name of the IED belonging to the current selected Sampled Values */ - currentSmvIedName: string | undefined | null; - - constructor() { - super(); - this.onIEDSelectEvent = this.onIEDSelectEvent.bind(this); - this.onSmvSelectEvent = this.onSmvSelectEvent.bind(this); - this.onIEDSubscriptionEvent = this.onIEDSubscriptionEvent.bind(this); - this.onViewChange = this.onViewChange.bind(this); - - const parentDiv = this.closest('.container'); - if (parentDiv) { - parentDiv.addEventListener('ied-select', this.onIEDSelectEvent); - parentDiv.addEventListener('smv-select', this.onSmvSelectEvent); - parentDiv.addEventListener( - 'smv-subscription', - this.onIEDSubscriptionEvent - ); - parentDiv.addEventListener('view', this.onViewChange); - } - } - - private async onIEDSelectEvent(event: IEDSelectEvent) { - if (!event.detail.ied) return; - this.currentSelectedIed = event.detail.ied!; - - this.resetElements(); - - const subscribedInputs = this.currentSelectedIed.querySelectorAll( - `LN0 > Inputs, LN > Inputs` - ); - - Array.from(this.doc.querySelectorAll('SampledValueControl')) - .filter(cb => cb.hasAttribute('datSet')) - .forEach(control => { - const ied = control.closest('IED')!; - - if ( - ied.getAttribute('name') == - this.currentSelectedIed?.getAttribute('name') - ) - return; - - /** If no Inputs is available, it's automatically available. */ - if (subscribedInputs.length == 0) { - this.availableElements.push({ element: control }); - return; - } - - let numberOfLinkedExtRefs = 0; - const dataSet = ied.querySelector( - `DataSet[name="${control.getAttribute('datSet')}"]` - ); - - if (!dataSet) return; - - dataSet!.querySelectorAll('FCDA').forEach(fcda => { - subscribedInputs.forEach(inputs => { - if (getExtRef(inputs, fcda, this.currentSelectedSmvControl)) { - numberOfLinkedExtRefs++; - } - }); - }); - - if (numberOfLinkedExtRefs == 0) { - this.availableElements.push({ element: control }); - return; - } - - if (numberOfLinkedExtRefs >= dataSet!.querySelectorAll('FCDA').length) { - this.subscribedElements.push({ element: control }); - } else { - this.availableElements.push({ element: control, partial: true }); - } - }); - - this.requestUpdate(); - } - - private async onSmvSelectEvent(event: SmvSelectEvent) { - if (!event.detail.dataset || !event.detail.smvControl) return; - - this.currentSelectedSmvControl = event.detail.smvControl; - this.currentUsedDataset = event.detail.dataset; - - this.currentSmvIedName = this.currentSelectedSmvControl - ?.closest('IED') - ?.getAttribute('name'); - - this.subscribedElements = []; - this.availableElements = []; - - Array.from(this.doc.querySelectorAll(':root > IED')) - .filter(ied => ied.getAttribute('name') != this.currentSmvIedName) - .forEach(ied => { - const inputElements = ied.querySelectorAll(`LN0 > Inputs, LN > Inputs`); - - let numberOfLinkedExtRefs = 0; - - /** - * If no Inputs element is found, we can safely say it's not subscribed. - */ - if (!inputElements) { - this.availableElements.push({ element: ied }); - return; - } - - /** - * Count all the linked ExtRefs. - */ - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - inputElements.forEach(inputs => { - if (getExtRef(inputs, fcda, this.currentSelectedSmvControl)) { - numberOfLinkedExtRefs++; - } - }); - }); - - /** - * Make a distinction between not subscribed at all, - * partially subscribed and fully subscribed. - */ - if (numberOfLinkedExtRefs == 0) { - this.availableElements.push({ element: ied }); - return; - } - - if ( - numberOfLinkedExtRefs >= - this.currentUsedDataset!.querySelectorAll('FCDA').length - ) { - this.subscribedElements.push({ element: ied }); - } else { - this.availableElements.push({ element: ied, partial: true }); - } - }); - - this.requestUpdate(); - } - - private async onIEDSubscriptionEvent(event: SmvSubscriptionEvent) { - let iedToSubscribe = event.detail.element; - - if (view == View.SUBSCRIBER) { - const dataSetName = event.detail.element.getAttribute('datSet'); - this.currentUsedDataset = - event.detail.element.parentElement?.querySelector( - `DataSet[name="${dataSetName}"]` - ); - this.currentSelectedSmvControl = event.detail.element; - this.currentSmvIedName = event.detail.element - .closest('IED') - ?.getAttribute('name'); - iedToSubscribe = this.currentSelectedIed!; - } - - switch (event.detail.subscribeStatus) { - case SubscribeStatus.Full: { - this.unsubscribe(iedToSubscribe); - break; - } - case SubscribeStatus.Partial: { - this.subscribe(iedToSubscribe); - break; - } - case SubscribeStatus.None: { - this.subscribe(iedToSubscribe); - break; - } - } - } - - private async onViewChange(event: ViewEvent) { - view = event.detail.view; - - this.currentSelectedIed = undefined; - this.currentSelectedSmvControl = undefined; - - this.resetElements(); - this.requestUpdate(); - } - - private async subscribe(ied: Element): Promise { - if (!ied.querySelector('LN0')) return; - - let inputsElement = ied.querySelector('LN0 > Inputs'); - if (!inputsElement) - inputsElement = createElement(ied.ownerDocument, 'Inputs', {}); - - const complexAction: ComplexAction = { - actions: [], - title: get(`subscription.connect`), - }; - - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - if ( - !existExtRef(inputsElement!, fcda, this.currentSelectedSmvControl) && - canCreateValidExtRef(fcda, this.currentSelectedSmvControl) - ) { - const extRef = createExtRefElement( - this.currentSelectedSmvControl, - fcda - ); - - if (inputsElement?.parentElement) - complexAction.actions.push({ - new: { parent: inputsElement!, element: extRef }, - }); - else inputsElement?.appendChild(extRef); - } - }); - - // we need to extend the actions array with the actions for the instantiation of the LSVS - const supervisionActions = instantiateSubscriptionSupervision( - this.currentSelectedSmvControl, - ied - ); - - if (inputsElement.parentElement) { - complexAction.actions.concat(supervisionActions); - } else { - /** If the IED doesn't have a Inputs element, just append it to the first LN0 element. */ - const inputAction: (Create | Move)[] = [ - { - new: { parent: ied.querySelector('LN0')!, element: inputsElement }, - }, - ]; - complexAction.actions = inputAction.concat(supervisionActions); - } - this.dispatchEvent(newActionEvent(complexAction)); - } - - private async unsubscribe(ied: Element): Promise { - const actions: Delete[] = []; - ied.querySelectorAll('LN0 > Inputs, LN > Inputs').forEach(inputs => { - this.currentUsedDataset!.querySelectorAll('FCDA').forEach(fcda => { - const extRef = getExtRef(inputs, fcda, this.currentSelectedSmvControl); - if (extRef) actions.push({ old: { parent: inputs, element: extRef } }); - }); - }); - - // Check if empty Input Element should also be removed. - actions.push(...emptyInputsDeleteActions(actions)); - - // we need to extend the actions array with the actions for removing the supervision - actions.push( - ...removeSubscriptionSupervision(this.currentSelectedSmvControl, ied) - ); - - this.dispatchEvent( - newActionEvent({ - title: get('subscription.disconnect'), - actions: actions, - }) - ); - } - - renderSubscriber(status: SubscribeStatus, element: Element): TemplateResult { - let firstSubscribedExtRef: Element | null = null; - let supervisionNode: Element | null = null; - if (status !== SubscribeStatus.None) { - if (view === View.PUBLISHER) { - firstSubscribedExtRef = getFirstSubscribedExtRef( - this.currentSelectedSmvControl!, - element - ); - supervisionNode = getExistingSupervision(firstSubscribedExtRef!); - } else { - firstSubscribedExtRef = getFirstSubscribedExtRef( - element, - this.currentSelectedIed! - ); - supervisionNode = getExistingSupervision(firstSubscribedExtRef!); - } - } - return html` { - this.dispatchEvent( - newSmvSubscriptionEvent(element, status ?? SubscribeStatus.None) - ); - }} - graphic="avatar" - ?hasMeta=${supervisionNode !== null} - > - ${view == View.PUBLISHER - ? element.getAttribute('name') - : element.getAttribute('name') + - ` (${element.closest('IED')?.getAttribute('name')})`} - ${status == SubscribeStatus.Full ? html`clear` : html`add`} - ${supervisionNode !== null - ? html`monitor_heart` - : nothing} - `; - } - - renderUnSubscribers(elements: ListElement[]): TemplateResult { - return html` - ${get('subscription.subscriber.availableToSubscribe')} - -
  • - ${elements.length > 0 - ? elements.map(element => - this.renderSubscriber(SubscribeStatus.None, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderPartiallySubscribers(elements: ListElement[]): TemplateResult { - return html` - ${get('subscription.subscriber.partiallySubscribed')} - -
  • - ${elements.length > 0 - ? elements.map(element => - this.renderSubscriber(SubscribeStatus.Partial, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderFullSubscribers(): TemplateResult { - return html` - ${get('subscription.subscriber.subscribed')} - -
  • - ${this.subscribedElements.length > 0 - ? this.subscribedElements.map(element => - this.renderSubscriber(SubscribeStatus.Full, element.element) - ) - : html` - ${get('subscription.none')} - `}`; - } - - renderTitle(): TemplateResult { - const gseControlName = - this.currentSelectedSmvControl?.getAttribute('name') ?? undefined; - - return view == View.PUBLISHER - ? html`

    - ${get('subscription.smv.publisher.subscriberTitle', { - selected: gseControlName - ? this.currentSmvIedName + ' > ' + gseControlName - : 'Sampled Value', - })} -

    ` - : html`

    - ${get('subscription.smv.subscriber.publisherTitle', { - selected: this.currentSelectedIed - ? this.currentSelectedIed.getAttribute('name')! - : 'IED', - })} -

    `; - } - - protected firstUpdated(): void { - this.currentSelectedIed = undefined; - } - - render(): TemplateResult { - return html` -
    - ${this.renderTitle()} - ${this.availableElements.length != 0 || - this.subscribedElements.length != 0 - ? html`
    - - ${this.renderFullSubscribers()} - ${this.renderPartiallySubscribers( - this.availableElements.filter(element => element.partial) - )} - ${this.renderUnSubscribers( - this.availableElements.filter(element => !element.partial) - )} - -
    ` - : html` - - ${ - view == View.PUBLISHER - ? get('subscription.subscriber.noControlBlockSelected') - : get('subscription.subscriber.noIedSelected') - } - - - `} -
    - `; - } - - static styles = css` - ${styles} - - .wrapper { - height: 100vh; - overflow-y: scroll; - } - `; -} diff --git a/packages/plugins/src/editors/substation/bay-editor.ts b/packages/plugins/src/editors/substation/bay-editor.ts deleted file mode 100644 index 18f733a886..0000000000 --- a/packages/plugins/src/editors/substation/bay-editor.ts +++ /dev/null @@ -1,294 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - query, - state, - TemplateResult, -} from 'lit-element'; -import { classMap } from 'lit-html/directives/class-map'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button'; -import '@material/mwc-textfield'; -import { Dialog } from '@material/mwc-dialog'; -import { Menu } from '@material/mwc-menu'; -import { IconButton } from '@material/mwc-icon-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/action-pane.js'; -import './ied-editor.js'; -import './conducting-equipment-editor.js'; -import './general-equipment-editor.js'; -import './powertransformer-editor.js'; -import { VoltageLevelEditor } from './voltage-level-editor.js'; -import { - newWizardEvent, - SCLTag, - tags, -} from '@openscd/open-scd/src/foundation.js'; - -import { - getChildElementsByTagName, -} from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { - bayIcon, - voltageLevelIcon, -} from '@openscd/open-scd/src/icons/icons.js'; -import { emptyWizard, wizards } from '../../wizards/wizard-library.js'; -import { - cloneSubstationElement, - renderGeneralEquipment, - redirectDialog, - startMove, - styles, -} from './foundation.js'; - -function childTags(element: Element | null | undefined): SCLTag[] { - if (!element) return []; - - return tags[element.tagName].children.filter( - child => wizards[child].create !== emptyWizard - ); -} - -/** [[`SubstationEditor`]] subeditor for a `Bay` element. */ -@customElement('bay-editor') -export class BayEditor extends LitElement { - /** The document being edited as provided to editor by [[`Zeroline`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property({ attribute: false }) - element!: Element; - @property({ type: Boolean }) - readonly = false; - /** Whether `Function` and `SubFunction` are rendered */ - @property({ type: Boolean }) - showfunctions = false; - - @property({ type: String }) - get header(): string { - const name = this.element.getAttribute('name') ?? ''; - const desc = this.element.getAttribute('desc'); - - return `${name} ${desc ? `- ${desc}` : ''}`; - } - - @property({ attribute: false }) - getAttachedIeds?: (element: Element) => Element[] = () => { - return []; - }; - - @state() - cloneUI = false; - - @query('mwc-dialog') dialog!: Dialog; - @query('mwc-menu') addMenu!: Menu; - @query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton; - - openEditWizard(): void { - const wizard = wizards['Bay'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - /** Opens a [[`WizardDialog`]] for editing `LNode` connections. */ - openLNodeWizard(): void { - const wizard = wizards['LNode'].create(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - private openCreateWizard(tagName: string): void { - const wizard = wizards[tagName].create(this.element!); - - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - updated(): void { - this.addMenu.anchor = this.addButton; - } - - private renderRedirectUI(): TemplateResult { - if (!this.cloneUI) return html``; - - return redirectDialog(this.element); - } - - private renderLNodes(): TemplateResult { - if (!this.showfunctions) return html``; - - const lNodes = getChildElementsByTagName(this.element, 'LNode'); - - return lNodes.length - ? html`
    - ${lNodes.map( - lNode => - html`` - )} -
    ` - : html``; - } - - renderFunctions(): TemplateResult { - if (!this.showfunctions) return html``; - - const functions = getChildElementsByTagName(this.element, 'Function'); - return html` ${functions.map( - fUnction => - html`` - )}`; - } - - renderIedContainer(): TemplateResult { - const ieds = this.getAttachedIeds?.(this.element) ?? []; - return ieds?.length - ? html`
    - ${ieds.map( - ied => - html`` - )} -
    ` - : html``; - } - - private renderAddButtons(): TemplateResult[] { - return childTags(this.element).map( - child => - html`${child}` - ); - } - - render(): TemplateResult { - return html`${this.renderRedirectUI()} - ${bayIcon} - - - - - cloneSubstationElement(this)} - > - - - this.openEditWizard()} - > - - - startMove(this, BayEditor, [VoltageLevelEditor])} - > - - - this.remove()} - > - - - (this.addMenu.open = true)} - > { - const tagName = ((e.target).selected).value; - this.openCreateWizard(tagName); - }} - >${this.renderAddButtons()} - - ${renderGeneralEquipment(this.doc, this.element, this.showfunctions)} - ${this.renderIedContainer()}${this.renderLNodes()}${this.renderFunctions()} -
    - ${Array.from( - getChildElementsByTagName(this.element, 'PowerTransformer') - ).map( - pwt => - html`` - )} - ${Array.from( - getChildElementsByTagName(this.element, 'ConductingEquipment') - ).map( - voltageLevel => - html`` - )} -
    - `; - } - - static styles = css` - ${styles} - - .content.actionicon { - display: grid; - grid-gap: 12px; - padding: 12px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(64px, auto)); - } - - conducting-equipment-editor[showfunctions] { - margin: 4px 8px 16px; - } - `; -} diff --git a/packages/plugins/src/editors/substation/conducting-equipment-editor.ts b/packages/plugins/src/editors/substation/conducting-equipment-editor.ts deleted file mode 100644 index 88b02b4094..0000000000 --- a/packages/plugins/src/editors/substation/conducting-equipment-editor.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { - css, - customElement, - html, - LitElement, - property, - query, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-fab'; -import '@material/mwc-icon'; -import '@material/mwc-icon-button'; -import '@material/mwc-menu'; -import { Menu } from '@material/mwc-menu'; -import { IconButton } from '@material/mwc-icon-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import '@openscd/open-scd/src/action-icon.js'; -import '@openscd/open-scd/src/action-pane.js'; -import './eq-function-editor.js'; -import './l-node-editor.js'; -import './sub-equipment-editor.js'; -import { startMove, getIcon, styles } from './foundation.js'; -import { - newWizardEvent, - SCLTag, - tags, -} from '@openscd/open-scd/src/foundation.js'; - -import { - getChildElementsByTagName, -} from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { BayEditor } from './bay-editor.js'; -import { emptyWizard, wizards } from '../../wizards/wizard-library.js'; - -function childTags(element: Element | null | undefined): SCLTag[] { - if (!element) return []; - - return tags[element.tagName].children.filter( - child => wizards[child].create !== emptyWizard - ); -} - -/** [[`SubstationEditor`]] subeditor for a `ConductingEquipment` element. */ -@customElement('conducting-equipment-editor') -export class ConductingEquipmentEditor extends LitElement { - /** The document being edited as provided to editor by [[`Zeroline`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - /** SCL element ConductingEquipment */ - @property({ attribute: false }) - element!: Element; - /** ConductingEquipment name attribute */ - @property({ type: String }) - get name(): string { - return this.element.getAttribute('name') ?? ''; - } - /** Whether `EqFunction`, `SubEqFunction` and `SubEquipment` are rendered */ - @property({ type: Boolean }) - showfunctions = false; - - @query('mwc-menu') addMenu!: Menu; - @query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton; - - private openEditWizard(): void { - const wizard = wizards['ConductingEquipment'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private openLNodeWizard(): void { - const wizard = wizards['LNode'].create(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - private openCreateWizard(tagName: string): void { - const wizard = wizards[tagName].create(this.element!); - - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - remove(): void { - if (this.element) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement!, - element: this.element, - reference: this.element.nextSibling, - }, - }) - ); - } - - updated(): void { - if (this.addMenu && this.addButton) - this.addMenu.anchor = this.addButton; - } - - private renderLNodes(): TemplateResult { - const lNodes = getChildElementsByTagName(this.element, 'LNode'); - - return lNodes.length - ? html`
    - ${lNodes.map( - lNode => - html`` - )} -
    ` - : html``; - } - - renderEqFunctions(): TemplateResult { - if (!this.showfunctions) return html``; - - const eqFunctions = getChildElementsByTagName(this.element, 'EqFunction'); - return html` ${eqFunctions.map( - eqFunction => - html`` - )}`; - } - - private renderSubEquipments(): TemplateResult { - if (!this.showfunctions) return html``; - - const subEquipments = getChildElementsByTagName( - this.element, - 'SubEquipment' - ); - - return html` ${subEquipments.map( - subEquipment => - html`` - )}`; - } - - private renderAddButtons(): TemplateResult[] { - return childTags(this.element).map( - child => - html`${child}` - ); - } - - renderContentPane(): TemplateResult { - return html`${getIcon(this.element)} - - - - - - - - - - - - (this.addMenu.open = true)} - > { - const tagName = ((e.target).selected).value; - this.openCreateWizard(tagName); - }} - >${this.renderAddButtons()} - `; - } - - renderContentIcon(): TemplateResult { - return html`${getIcon(this.element)} - - - - `; - } - - render(): TemplateResult { - if (this.showfunctions) - return html`${this.renderContentPane()}${this.renderLNodes()}${this.renderEqFunctions()}${this.renderSubEquipments()}`; - - return html`${this.renderContentIcon()}`; - } - - static styles = css` - ${styles} - - :host(.moving) { - opacity: 0.3; - } - - abbr { - text-decoration: none; - border-bottom: none; - } - `; -} diff --git a/packages/plugins/src/editors/substation/eq-function-editor.ts b/packages/plugins/src/editors/substation/eq-function-editor.ts deleted file mode 100644 index ab33705a43..0000000000 --- a/packages/plugins/src/editors/substation/eq-function-editor.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { - html, - LitElement, - TemplateResult, - property, - customElement, - state, - css, - query, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-menu'; -import { IconButton } from '@material/mwc-icon-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { Menu } from '@material/mwc-menu'; - -import '@openscd/open-scd/src/action-pane.js'; -import './eq-sub-function-editor.js'; -import './general-equipment-editor.js'; -import { - newWizardEvent, - SCLTag, - tags, -} from '@openscd/open-scd/src/foundation.js'; - -import { getChildElementsByTagName } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { emptyWizard, wizards } from '../../wizards/wizard-library.js'; -import { classMap } from 'lit-html/directives/class-map.js'; -import { renderGeneralEquipment } from './foundation.js'; - -function childTags(element: Element | null | undefined): SCLTag[] { - if (!element) return []; - - return tags[element.tagName].children.filter( - child => wizards[child].create !== emptyWizard - ); -} - -/** Pane rendering `EqFunction` element with its children */ -@customElement('eq-function-editor') -export class EqFunctionEditor extends LitElement { - /** The document being edited as provided to editor by [[`Zeroline`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - /** The edited `EqFunction` element */ - @property({ attribute: false }) - element!: Element; - - @property({ type: Boolean }) - showfunctions = false; - - @state() - private get header(): string { - const name = this.element.getAttribute('name'); - const desc = this.element.getAttribute('desc'); - const type = this.element.getAttribute('type'); - - return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`; - } - - @query('mwc-menu') addMenu!: Menu; - @query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton; - - private openEditWizard(): void { - const wizard = wizards['EqFunction'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - remove(): void { - if (this.element.parentElement) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement, - element: this.element, - }, - }) - ); - } - - private openCreateWizard(tagName: string): void { - const wizard = wizards[tagName].create(this.element!); - - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - updated(): void { - this.addMenu.anchor = this.addButton; - } - - private renderLNodes(): TemplateResult { - const lNodes = getChildElementsByTagName(this.element, 'LNode'); - - return lNodes.length - ? html`
    - ${lNodes.map( - lNode => - html`` - )} -
    ` - : html``; - } - - private renderEqSubFunctions(): TemplateResult { - const eqSubFunctions = getChildElementsByTagName( - this.element, - 'EqSubFunction' - ); - return html` ${eqSubFunctions.map( - eqSubFunction => - html`` - )}`; - } - - private renderAddButtons(): TemplateResult[] { - return childTags(this.element).map( - child => - html`${child}` - ); - } - - render(): TemplateResult { - return html` - this.openEditWizard()} - > - this.remove()} - > - (this.addMenu.open = true)} - > { - const tagName = ((e.target).selected).value; - this.openCreateWizard(tagName); - }} - >${this.renderAddButtons()} - ${renderGeneralEquipment(this.doc, this.element, this.showfunctions)} - ${this.renderLNodes()}${this.renderEqSubFunctions()}`; - } - - static styles = css` - abbr { - text-decoration: none; - border-bottom: none; - } - - .container.lnode { - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(64px, auto)); - } - `; -} diff --git a/packages/plugins/src/editors/substation/eq-sub-function-editor.ts b/packages/plugins/src/editors/substation/eq-sub-function-editor.ts deleted file mode 100644 index a6b3294a15..0000000000 --- a/packages/plugins/src/editors/substation/eq-sub-function-editor.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { - html, - LitElement, - TemplateResult, - property, - customElement, - state, - css, - query, -} from 'lit-element'; - -import { get } from 'lit-translate'; - -import '@material/mwc-icon-button'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-menu'; -import { IconButton } from '@material/mwc-icon-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { Menu } from '@material/mwc-menu'; - -import '@openscd/open-scd/src/action-pane.js'; -import './general-equipment-editor.js'; -import { - newWizardEvent, - SCLTag, - tags, -} from '@openscd/open-scd/src/foundation.js'; - -import { getChildElementsByTagName } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { emptyWizard, wizards } from '../../wizards/wizard-library.js'; -import { classMap } from 'lit-html/directives/class-map.js'; -import { renderGeneralEquipment } from './foundation.js'; - -function childTags(element: Element | null | undefined): SCLTag[] { - if (!element) return []; - - return tags[element.tagName].children.filter( - child => wizards[child].create !== emptyWizard - ); -} -/** Pane rendering `EqSubFunction` element with its children */ -@customElement('eq-sub-function-editor') -export class EqSubFunctionEditor extends LitElement { - /** The document being edited as provided to editor by [[`Zeroline`]]. */ - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - /** The edited `EqSubFunction` element */ - @property({ attribute: false }) - element!: Element; - @property({ type: Boolean }) - showfunctions = false; - @state() - private get header(): string { - const name = this.element.getAttribute('name'); - const desc = this.element.getAttribute('desc'); - const type = this.element.getAttribute('type'); - - return `${name}${desc ? ` - ${desc}` : ''}${type ? ` (${type})` : ''}`; - } - - @query('mwc-menu') addMenu!: Menu; - @query('mwc-icon-button[icon="playlist_add"]') addButton!: IconButton; - - private openEditWizard(): void { - const wizard = wizards['EqSubFunction'].edit(this.element); - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - remove(): void { - if (this.element.parentElement) - this.dispatchEvent( - newActionEvent({ - old: { - parent: this.element.parentElement, - element: this.element, - }, - }) - ); - } - - private openCreateWizard(tagName: string): void { - const wizard = wizards[tagName].create(this.element!); - - if (wizard) this.dispatchEvent(newWizardEvent(wizard)); - } - - updated(): void { - this.addMenu.anchor = this.addButton; - } - - private renderLNodes(): TemplateResult { - const lNodes = getChildElementsByTagName(this.element, 'LNode'); - - return lNodes.length - ? html`
    - ${lNodes.map( - lNode => - html`` - )} -
    ` - : html``; - } - - private renderEqSubFunctions(): TemplateResult { - const eqSubFunctions = getChildElementsByTagName( - this.element, - 'EqSubFunction' - ); - return html` ${eqSubFunctions.map( - eqSubFunction => - html`` - )}`; - } - - private renderAddButtons(): TemplateResult[] { - return childTags(this.element).map( - child => - html`${child}` - ); - } - - render(): TemplateResult { - return html` - this.openEditWizard()} - > - this.remove()} - > - (this.addMenu.open = true)} - > { - const tagName = ((e.target).selected).value; - this.openCreateWizard(tagName); - }} - >${this.renderAddButtons()} - ${renderGeneralEquipment(this.doc, this.element, this.showfunctions)} - ${this.renderLNodes()}${this.renderEqSubFunctions()}`; - } - - static styles = css` - abbr { - text-decoration: none; - border-bottom: none; - } - - .container.lnode { - display: grid; - grid-gap: 12px; - padding: 8px 12px 16px; - box-sizing: border-box; - grid-template-columns: repeat(auto-fit, minmax(64px, auto)); - } - `; -} diff --git a/packages/plugins/src/editors/substation/foundation.ts b/packages/plugins/src/editors/substation/foundation.ts deleted file mode 100644 index b407c19c97..0000000000 --- a/packages/plugins/src/editors/substation/foundation.ts +++ /dev/null @@ -1,686 +0,0 @@ -import { css, html, LitElement, TemplateResult } from 'lit-element'; -import { classMap } from 'lit-html/directives/class-map.js'; - -import './function-editor.js'; - -import { identity, isPublic } from '@openscd/open-scd/src/foundation.js'; - -import { getChildElementsByTagName } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { - circuitBreakerIcon, - disconnectorIcon, - currentTransformerIcon, - voltageTransformerIcon, - earthSwitchIcon, - generalConductingEquipmentIcon, -} from '@openscd/open-scd/src/icons/icons.js'; -import { typeStr } from '../../wizards/conductingequipment.js'; -import { Select } from '@material/mwc-select'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { get } from 'lit-translate'; - -import { BayEditor } from './bay-editor.js'; -import { VoltageLevelEditor } from './voltage-level-editor.js'; -import { SubstationEditor } from './substation-editor.js'; - -function containsReference(element: Element, iedName: string): boolean { - return Array.from(element.getElementsByTagName('LNode')) - .filter(isPublic) - .some(lnode => lnode.getAttribute('iedName') === iedName); -} - -function isReferencedItself(element: Element, iedName: string): boolean { - return (Array.from(element.children)).some( - child => - child.tagName === 'LNode' && child.getAttribute('iedName') === iedName - ); -} - -function hasReferencedChildren(element: Element, iedName: string): boolean { - const threshold = element.tagName === 'Bay' ? 0 : 1; - return ( - (Array.from(element.children)).filter(child => - containsReference(child, iedName) - ).length > threshold - ); -} - -function hasOurs(element: Element, iedName: string): boolean { - return Array.from(element.getElementsByTagName('LNode')) - .filter(isPublic) - .some(lnode => lnode.getAttribute('iedName') === iedName); -} - -function getOurs(element: Element, iedName: string): Element[] { - return Array.from(element.getElementsByTagName('LNode')) - .filter(isPublic) - .filter(lnode => lnode.getAttribute('iedName') === iedName); -} - -function hasTheirs(element: Element, iedName: string): boolean { - const ours = getOurs(element, iedName); - const scl = element.closest('SCL')!; - - return Array.from(scl.getElementsByTagName('LNode')) - .filter(isPublic) - .filter(lnode => lnode.getAttribute('iedName') === iedName) - .some(lnode => !ours.includes(lnode)); -} - -export function attachedIeds( - element: Element, - remainingIeds: Set -): Element[] { - const attachedIeds: Element[] = []; - for (const ied of remainingIeds) { - const iedName = ied.getAttribute('name')!; - - if (element.tagName === 'SCL') { - if (!hasOurs(element, iedName) || hasReferencedChildren(element, iedName)) - attachedIeds.push(ied); - - continue; - } - - if (hasTheirs(element, iedName)) continue; - if ( - hasReferencedChildren(element, iedName) || - isReferencedItself(element, iedName) - ) - attachedIeds.push(ied); - } - - for (const ied of attachedIeds) { - remainingIeds.delete(ied); - } - - return attachedIeds; -} - -export function getAttachedIeds( - doc: XMLDocument -): (element: Element) => Element[] { - return (element: Element) => { - const ieds = new Set( - Array.from(doc.querySelectorAll('IED')).filter(isPublic) - ); - - return attachedIeds(element, ieds); - }; -} - -/** Whether the LNode reference valid relatively (IED agnostic) */ -function validRelativeReference( - ied: Element, - lNode: Element -): Element | undefined { - const [ldInst, prefix, lnClass, lnInst] = [ - 'ldInst', - 'prefix', - 'lnClass', - 'lnInst', - ].map(name => lNode.getAttribute(name)); - - return Array.from(ied.querySelectorAll('LN, LN0')) - .filter(isPublic) - .find( - anyLn => - anyLn?.closest('LDevice')?.getAttribute('inst') === ldInst && - (anyLn.getAttribute('prefix') ?? '') === (prefix ?? '') && - (anyLn.getAttribute('lnClass') ?? '') === (lnClass ?? '') && - (anyLn.getAttribute('inst') ?? '') === (lnInst ?? '') - ); -} - -/** Identity of LNode with iedName !== None is global and independent of parent*/ -function lNodeRegistry(doc: XMLDocument): (newLNode: Element) => boolean { - const lNodes = new Set( - Array.from(doc.querySelectorAll('LNode')) - .filter(isPublic) - .map(lNode => identity(lNode)) - ); - - return (newLNode: Element) => { - if (lNodes.has(identity(newLNode))) return true; - - lNodes.add(identity(newLNode)); - return false; - }; -} - -/** - * Clones - deep copy - substation element cloneEntity with removed single line diagram - * @param cloneEntity - substation element to be cloned - * @param newName - name of the clone - * @param iedRedirect - redirection information for LNode elements (all LNodes's are removed for undefined) - * @returns a deep cloned node without single line diagram information - */ -export function substationElementClone( - cloneEntity: Element, - newName: string, - iedRedirect?: Partial> -): Element { - const usedLNodes = lNodeRegistry(cloneEntity.ownerDocument); - - const clone: Element = cloneEntity.cloneNode(true); - clone.querySelectorAll('LNode').forEach(lNode => { - const oldIedName = lNode.getAttribute('iedName'); - - if (oldIedName === 'None') return; // non referenced LNode - if (!oldIedName) { - //iedName required - lNode.parentElement?.removeChild(lNode); - return; - } - - // no or invalid user choice - if (!iedRedirect || !iedRedirect[oldIedName]) { - lNode.parentElement?.removeChild(lNode); - return; - } - - // user decide to remove LNode - if (iedRedirect[oldIedName] === 'No') { - lNode.parentElement?.removeChild(lNode); - return; - } - - lNode.setAttribute('iedName', iedRedirect[oldIedName]!); - - // new LNode already in use - if (usedLNodes(lNode)) { - lNode.parentElement?.removeChild(lNode); - return; - } - - const ied = cloneEntity.ownerDocument.querySelector( - `IED[name="${iedRedirect[oldIedName]}"]` - ); - if (!ied || !validRelativeReference(ied, lNode)) { - lNode.parentElement?.removeChild(lNode); - return; - } - }); - - clone - .querySelectorAll('Terminal:not([cNodeName="grounded"])') - .forEach(terminal => terminal.parentElement?.removeChild(terminal)); - // FIXME(JakobVogelsang): for the moment removes terminal as well. - // For later terminal keep might be the better choice - - clone - .querySelectorAll('ConnectivityNode') - .forEach(condNode => condNode.parentElement?.removeChild(condNode)); - // FIXME(JakobVogelsang): for the moment beeing connectivity node remove as well. - // For later connectivity keep might be the better choice to preserve substation structure - - clone.setAttribute('name', newName); - - return clone; -} - -function cloneWithRedirect(evt: Event, cloneEntity: Element): void { - const dialog = (evt.target)?.parentElement; - if (!dialog) return; - - const children = <(Select | WizardTextField)[]>( - Array.from(dialog.querySelectorAll('mwc-select, wizard-textfield')) - ); - if (!children.every(child => child.checkValidity())) return; - - const nameField = dialog.querySelector('wizard-textfield')!; - - const iedRedirects = Array.from( - dialog.querySelectorAllinputs.find(i => i.label === 'values'); - const selectedElement = values.selected - ? templates.querySelector(`DAType[id="${values.selected.value}"]`) - : null; - const element = values.selected - ? selectedElement!.cloneNode(true) - : createElement(parent.ownerDocument, 'DAType', {}); - - element.setAttribute('id', id); - if (desc) element.setAttribute('desc', desc); - - const actions: Create[] = []; - - if (selectedElement) - addReferencedDataTypes(selectedElement, parent).forEach(action => - actions.push(action) - ); - - actions.push({ - new: { - parent, - element, - }, - }); - - return unifyCreateActionArray(actions); - }; -} - -export function createDATypeWizard( - parent: Element, - templates: Document -): Wizard { - return [ - { - title: get('datype.wizard.title.add'), - primary: { - icon: 'add', - label: get('add'), - action: addPredefinedDAType(parent, templates), - }, - content: [ - html` - ${Array.from(templates.querySelectorAll('DAType')).map( - datype => - html`${datype.getAttribute('id')?.replace('OpenSCD_', '')} - ${datype.querySelectorAll('BDA').length} - ` - )} - `, - html``, - html``, - ], - }, - ]; -} diff --git a/packages/plugins/src/editors/templates/dotype-wizards.ts b/packages/plugins/src/editors/templates/dotype-wizards.ts deleted file mode 100644 index 71985dd492..0000000000 --- a/packages/plugins/src/editors/templates/dotype-wizards.ts +++ /dev/null @@ -1,448 +0,0 @@ -import { html } from 'lit-html'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; -import { Select } from '@material/mwc-select'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { List } from '@material/mwc-list'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { - find, - getValue, - identity, - isPublic, - newSubWizardEvent, - newWizardEvent, - Wizard, - WizardActor, - WizardInputElement, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement, createElement } from '@openscd/xml'; - -import { - Create, - EditorAction, - newActionEvent, - Replace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { createDaWizard, editDAWizard } from '../../wizards/da.js'; -import { patterns } from '../../wizards/foundation/limits.js'; -import { - addReferencedDataTypes, - allDataTypeSelector, - CreateOptions, - unifyCreateActionArray, - UpdateOptions, - WizardOptions, -} from './foundation.js'; - -function remove(element: Element): WizardMenuActor { - return (wizard: Element): void => { - wizard.dispatchEvent( - newActionEvent({ old: { parent: element.parentElement!, element } }) - ); - wizard.dispatchEvent(newWizardEvent()); - }; -} - -function updateSDoAction(element: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const name = getValue(inputs.find(i => i.label === 'name')!)!; - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const type = getValue(inputs.find(i => i.label === 'type')!)!; - - const actions: EditorAction[] = []; - if ( - name === element.getAttribute('name') && - desc === element.getAttribute('desc') && - type === element.getAttribute('type') - ) { - return []; - } - - const newElement = cloneElement(element, { name, desc, type }); - actions.push({ old: { element }, new: { element: newElement } }); - - return actions; - }; -} - -function createSDoAction(parent: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const name = getValue(inputs.find(i => i.label === 'name')!)!; - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const type = getValue(inputs.find(i => i.label === 'type')!); - - const actions: EditorAction[] = []; - - const element = createElement(parent.ownerDocument, 'SDO', { - name, - desc, - type, - }); - actions.push({ - new: { - parent, - element, - }, - }); - - return actions; - }; -} - -function sDOWizard(options: WizardOptions): Wizard | undefined { - const doc = (options).doc - ? (options).doc - : (options).parent.ownerDocument; - const sdo = find(doc, 'SDO', (options).identity ?? NaN); - - const [title, action, type, menuActions, name, desc] = sdo - ? [ - get('sdo.wizard.title.edit'), - updateSDoAction(sdo), - sdo.getAttribute('type'), - [{ icon: 'delete', label: get('remove'), action: remove(sdo) }], - sdo.getAttribute('name'), - sdo.getAttribute('desc'), - ] - : [ - get('sdo.wizard.title.add'), - createSDoAction((options).parent), - null, - undefined, - '', - null, - ]; - - const types = Array.from(doc.querySelectorAll('DOType')) - .filter(isPublic) - .filter(type => type.getAttribute('id')); - - return [ - { - title, - element: sdo ?? undefined, - primary: { icon: '', label: get('save'), action }, - menuActions, - content: [ - html` - >`, - html``, - html`${types.map( - dataType => - html`${dataType.id}` - )}`, - ], - }, - ]; -} - -function addPredefinedDOType( - parent: Element, - templates: XMLDocument -): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const id = getValue(inputs.find(i => i.label === 'id')!); - - if (!id) return []; - - const existId = Array.from( - templates.querySelectorAll(allDataTypeSelector) - ).some(type => type.getAttribute('id') === id); - - if (existId) return []; - - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const cdc = getValue(inputs.find(i => i.label === 'cdc')!)!; - - const values = ( - (e.target).value; - const cdc = - templates.querySelector(`DOType[id="${doTypeId}"]`)?.getAttribute('cdc') ?? - null; - - if (cdc) cdcUI.value = cdc; - cdcUI.disabled = true; -} - -export function createDOTypeWizard( - parent: Element, - templates: Document -): Wizard { - return [ - { - title: get('dotype.wizard.title.add'), - primary: { - icon: 'add', - label: get('add'), - action: addPredefinedDOType(parent, templates), - }, - content: [ - html` onSelectTemplateDOType(e, templates)} - > - ${Array.from(templates.querySelectorAll('DOType')).map( - datype => - html`${datype.getAttribute('id')?.replace('OpenSCD_', '')} - ${datype.querySelectorAll('SDO,DA').length} - ` - )} - `, - html``, - html``, - html``, - ], - }, - ]; -} - -function openAddSdo(parent: Element): WizardMenuActor { - return (wizard: Element): void => { - wizard.dispatchEvent(newSubWizardEvent(() => sDOWizard({ parent })!)); - }; -} - -function openAddDa(parent: Element): WizardMenuActor { - return (wizard: Element): void => { - wizard.dispatchEvent(newSubWizardEvent(() => createDaWizard(parent)!)); - }; -} - -function updateDOTypeAction(element: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const id = getValue(inputs.find(i => i.label === 'id')!)!; - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const cdc = getValue(inputs.find(i => i.label === 'CDC')!)!; - - if ( - id === element.getAttribute('id') && - desc === element.getAttribute('desc') && - cdc == element.getAttribute('cdc') - ) - return []; - - const newElement = cloneElement(element, { id, desc, cdc }); - - const actions: Replace[] = []; - actions.push({ old: { element }, new: { element: newElement } }); - - const oldId = element.getAttribute('id')!; - Array.from( - element.ownerDocument.querySelectorAll( - `LNodeType > DO[type="${oldId}"], DOType > SDO[type="${oldId}"]` - ) - ).forEach(oldDo => { - const newDo = oldDo.cloneNode(false); - newDo.setAttribute('type', id); - - actions.push({ old: { element: oldDo }, new: { element: newDo } }); - }); - - return [ - { title: get('dotype.action.edit', { oldId, newId: id }), actions }, - ]; - }; -} - -export function dOTypeWizard( - dOTypeIdentity: string, - doc: XMLDocument -): Wizard | undefined { - const dotype = find(doc, 'DOType', dOTypeIdentity); - if (!dotype) return undefined; - - return [ - { - title: get('dotype.wizard.title.edit'), - element: dotype, - primary: { - icon: '', - label: get('save'), - action: updateDOTypeAction(dotype), - }, - menuActions: [ - { - label: get('remove'), - icon: 'delete', - action: remove(dotype), - }, - { - label: get('scl.DO'), - icon: 'playlist_add', - action: openAddSdo(dotype), - }, - { - label: get('scl.DA'), - icon: 'playlist_add', - action: openAddDa(dotype), - }, - ], - content: [ - html``, - html``, - html``, - html` - { - const item = (e.target).selected; - - const daIdentity = ((e.target).selected).value; - const da = find(doc, 'DA', daIdentity); - - const wizard = item.classList.contains('DA') - ? da - ? editDAWizard(da) - : undefined - : sDOWizard({ - identity: item.value, - doc, - }); - - if (wizard) e.target!.dispatchEvent(newSubWizardEvent(wizard)); - }} - > - ${Array.from(dotype.querySelectorAll('SDO, DA')).map( - daorsdo => - html`${daorsdo.getAttribute('name')}${daorsdo.tagName === 'SDO' || - daorsdo.getAttribute('bType') === 'Enum' || - daorsdo.getAttribute('bType') === 'Struct' - ? '#' + daorsdo.getAttribute('type') - : daorsdo.getAttribute('bType')}` - )} - - `, - ], - }, - ]; -} diff --git a/packages/plugins/src/editors/templates/enumtype-wizard.ts b/packages/plugins/src/editors/templates/enumtype-wizard.ts deleted file mode 100644 index 4ef6d1e930..0000000000 --- a/packages/plugins/src/editors/templates/enumtype-wizard.ts +++ /dev/null @@ -1,368 +0,0 @@ -import { html } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-select'; -import { List } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { SingleSelectedEvent } from '@material/mwc-list/mwc-list-foundation'; -import { Select } from '@material/mwc-select'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { - find, - getValue, - identity, - newSubWizardEvent, - newWizardEvent, - patterns, - Wizard, - WizardActor, - WizardInputElement, - WizardMenuActor, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement, createElement } from '@openscd/xml'; - -import { - EditorAction, - newActionEvent, - Replace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { CreateOptions, UpdateOptions, WizardOptions } from './foundation.js'; - -function remove(element: Element): WizardMenuActor { - return (wizard: Element): void => { - wizard.dispatchEvent( - newActionEvent({ old: { parent: element.parentElement!, element } }) - ); - wizard.dispatchEvent(newWizardEvent()); - }; -} - -function nextOrd(parent: Element): string { - const maxOrd = Math.max( - ...Array.from(parent.children).map(child => - parseInt(child.getAttribute('ord') ?? '-2', 10) - ) - ); - return isFinite(maxOrd) ? (maxOrd + 1).toString(10) : '0'; -} - -function createEnumValAction(parent: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const value = getValue(inputs.find(i => i.label === 'value')!); - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const ord = - getValue(inputs.find(i => i.label === 'ord')!) || nextOrd(parent); - - const element = createElement(parent.ownerDocument, 'EnumVal', { - ord, - desc, - }); - - element.textContent = value; - - const action = { - new: { - parent, - element, - }, - }; - - return [action]; - }; -} - -function updateEnumValAction(element: Element): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const value = getValue(inputs.find(i => i.label === 'value')!) ?? ''; - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const ord = - getValue(inputs.find(i => i.label === 'ord')!) || - element.getAttribute('ord') || - nextOrd(element.parentElement!); - - if ( - value === element.textContent && - desc === element.getAttribute('desc') && - ord === element.getAttribute('ord') - ) - return []; - - const newElement = cloneElement(element, { desc, ord }); - newElement.textContent = value; - - return [{ old: { element }, new: { element: newElement } }]; - }; -} - -function eNumValWizard(options: WizardOptions): Wizard { - const doc = (options).doc - ? (options).doc - : (options).parent.ownerDocument; - const enumval = find( - doc, - 'EnumVal', - (options).identity ?? NaN - ); - - const [title, action, ord, desc, value, menuActions] = enumval - ? [ - get('enum-val.wizard.title.edit'), - updateEnumValAction(enumval), - enumval.getAttribute('ord'), - enumval.getAttribute('desc'), - enumval.textContent, - [ - { - icon: 'delete', - label: get('remove'), - action: remove(enumval), - }, - ], - ] - : [ - get('enum-val.wizard.title.add'), - createEnumValAction((options).parent), - nextOrd((options).parent), - null, // desc is uncommon on EnumVal - '', - undefined, - ]; - - return [ - { - title, - element: enumval ?? undefined, - primary: { - icon: '', - label: 'Save', - action: action, - }, - menuActions, - content: [ - html``, - html``, - html``, - ], - }, - ]; -} - -function createAction(parent: Element, templates: XMLDocument): WizardActor { - return (inputs: WizardInputElement[]): EditorAction[] => { - const id = getValue(inputs.find(i => i.label === 'id')!); - - if (!id) return []; - - const desc = getValue(inputs.find(i => i.label === 'desc')!); - const values = inputs.find(i => i.label === 'lnClass'))?.selected - ?.value; - const templateLNodeType = value - ? find(templates, 'LNodeType', value) - : null; - - const newLNodeType = templateLNodeType - ? templateLNodeType!.cloneNode(true) - : createElement(parent.ownerDocument, 'LNodeType', { - lnClass: value ?? '', - }); - - newLNodeType.setAttribute('id', id); - if (desc) newLNodeType.setAttribute('desc', desc); - - if (templateLNodeType) - return addPredefinedLNodeType(parent, newLNodeType, templateLNodeType); - - const allDo = getAllDataObjects(nsd74, value!, nsd7420); - wizard.dispatchEvent( - newWizardEvent(createLNodeTypeHelperWizard(parent, newLNodeType, allDo)) - ); - - wizard.dispatchEvent(newWizardEvent()); - return []; - }; -} - -function onLnClassChange(e: Event, templates: XMLDocument): void { - const identity = ( - this.dispatchEvent(newPendingStateEvent(this.getTemplateFile(evt)))} - /> - - { - const input = ( - this.shadowRoot!.querySelector('#template-file') - ); - input?.click(); - }} - > - - ${this.renderCloseButton()}`; - } - - private renderDialog( - content: TemplateResult, - heading: string - ): TemplateResult { - return html` - ${content} - `; - } - - render(): TemplateResult { - if (!this.doc) return html``; - - if (this.selectedProjectIed && this.selectedTemplateIed) { - return this.renderDialog( - this.renderCompare(), - get('compare-ied.resultTitle') - ); - } else if (this.templateDoc) { - return this.renderDialog( - this.renderIEDLists(), - get('compare-ied.selectIedTitle') - ); - } else { - return this.renderDialog( - this.renderSelectTemplateFile(), - get('compare-ied.selectProjectTitle') - ); - } - } - - static styles = css` - mwc-dialog { - --mdc-dialog-min-width: 64vw; - } - - .splitContainer { - display: flex; - padding: 8px 6px 16px; - height: 64vh; - } - - .iedList { - flex: 50%; - margin: 0px 6px 0px; - min-width: 300px; - height: 100%; - overflow-y: auto; - } - - .resultTitle { - font-weight: bold; - } - `; -} diff --git a/packages/plugins/src/menu/ExportCommunication.ts b/packages/plugins/src/menu/ExportCommunication.ts deleted file mode 100644 index 3b4d0b2c24..0000000000 --- a/packages/plugins/src/menu/ExportCommunication.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { LitElement, property } from 'lit-element'; -import { get } from 'lit-translate'; - -import { formatXml } from '@openscd/xml'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history'; - -function cloneAttributes(destElement: Element, sourceElement: Element) { - let attr; - const attributes = Array.prototype.slice.call(sourceElement.attributes); - while ((attr = attributes.pop())) { - destElement.setAttribute(attr.nodeName, attr.nodeValue); - } -} - -/** - * Take an XMLDocument and pretty-print, format it, attach it to a document link and then download it. - * @param doc - The XML document - * @param document - The element to attach to within the DOM - * @param filename - The filename to produce - * @returns The blob object that is serialised - */ -export function saveXmlBlob( - doc: XMLDocument, - document: Document, - filename: string -): void { - const blob = new Blob( - [formatXml(new XMLSerializer().serializeToString(doc))], - { - type: 'application/xml', - } - ); - - const a = document.createElement('a'); - a.download = filename; - a.href = URL.createObjectURL(blob); - a.dataset.downloadurl = ['application/xml', a.download, a.href].join(':'); - a.style.display = 'none'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - setTimeout(function () { - URL.revokeObjectURL(a.href); - }, 5000); -} - -/** - * Plug-in to allow exporting of the Communication SCL element as an XML file. - */ -export default class ExportCommunication extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - @property({ attribute: false }) doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @property({ attribute: false }) docName!: string; - - /** Entry point for this plug-in */ - async run(): Promise { - // create document - const sclNamespace = 'http://www.iec.ch/61850/2003/SCL'; - const sclDoc = document.implementation.createDocument( - sclNamespace, - 'SCL', - null - ); - const pi = sclDoc.createProcessingInstruction( - 'xml', - 'version="1.0" encoding="UTF-8"' - ); - sclDoc.insertBefore(pi, sclDoc.firstChild); - - // ensure schema revision and namespace definitions are transferred - cloneAttributes(sclDoc.documentElement, this.doc.documentElement); - - const communicationSection = this.doc.querySelector( - ':root > Communication' - ); - - if (communicationSection) { - const header = this.doc.querySelector(':root > Header')?.cloneNode(true); - const communication = this.doc - .querySelector(':root > Communication') - ?.cloneNode(true); - - if (header) sclDoc.documentElement.appendChild(header); - sclDoc.documentElement.appendChild(communication); - - const ending = this.docName.slice(0, -4); - let docName = `${this.docName}-Communication.scd`; - // use filename extension if there seems to be one - if (ending.slice(0, 1) === '.') { - docName = `${this.docName.slice(0, -4)}-Communication${ending}`; - } - saveXmlBlob(sclDoc, document, docName); - } else { - this.dispatchEvent( - newLogEvent({ - kind: 'warning', - title: get('exportCommunication.noCommunicationSection'), - }) - ); - } - } -} diff --git a/packages/plugins/src/menu/Help.ts b/packages/plugins/src/menu/Help.ts deleted file mode 100644 index 664b4c1ca0..0000000000 --- a/packages/plugins/src/menu/Help.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { html, LitElement } from 'lit-element'; -import { unsafeHTML } from 'lit-html/directives/unsafe-html'; -import * as marked from 'marked'; - -import '@material/mwc-icon'; - -import '@openscd/open-scd/src/finder-list.js'; -import { newWizardEvent, Wizard } from '@openscd/open-scd/src/foundation.js'; -import { openSCDIcon } from '@openscd/open-scd/src/icons/icons.js'; -import { Directory } from '@openscd/open-scd/src/finder-list.js'; - -const GITHUB_WIKI_LINK_PATTERN = /https:\/\/github\.com\/openscd\/open-scd\/wiki\/([^)]*)/g; -const MD_LINK_TITLE_PATTERN ='([^\\]]*)'; -const HYPHEN_PATTERN = /-/g; - -function aboutBox(version: string) { - return html`
    -
    - ${openSCDIcon} -
    -

    OpenSCD

    - V${version} -
    -
    -
    -
    -

    Licences

    -

    - The IEC 61850 XSD and NSD code components used are distributed - under their - end user licence agreement.
    This - project's source code is licensed under the - Apache 2.0 license and available on - GitHub. -

    -

    © 2020-2021 OMICRON electronics GmbH

    -

    Help

    -
    `; -} - -async function getLinkedPages(path: string[]): Promise { - const edition = await (await fetch('/manifest.json')).json(); - if (path.length === 0) { - return { path, header: aboutBox(edition.version), entries: ['Home'] }; - } - - const page = path[path.length - 1].replace(/ /g, '-'); - const res = await fetch(`/openscd/public/md/${page}.md`); - const md = await res.text(); - const MD_LINK_REPLACEMENT = `$1` - const unlinkedMd = md.replace( - new RegExp(`\\[${MD_LINK_TITLE_PATTERN}\\]\\(${GITHUB_WIKI_LINK_PATTERN.source}\\)`, 'g'), - MD_LINK_REPLACEMENT - ); - - const header = html`
    - ${page === 'Home' ? aboutBox(edition.version) : html``} - ${unsafeHTML(marked.parse(unlinkedMd))} -
    `; - const entries = Array.from( - md.matchAll( new RegExp(`\\(${GITHUB_WIKI_LINK_PATTERN.source}\\)`, 'g')) - - ).map(([_, child]) => child.replace(HYPHEN_PATTERN, ' ')); - - return { path, header, entries }; -} - -export function aboutBoxWizard(): Wizard { - return [ - { - title: 'Help', - content: [ - html``, - ], - }, - ]; -} - -export default class HelpPlugin extends LitElement { - async run(): Promise { - this.dispatchEvent(newWizardEvent(aboutBoxWizard())); - } -} diff --git a/packages/plugins/src/menu/ImportIEDs.ts b/packages/plugins/src/menu/ImportIEDs.ts deleted file mode 100644 index 1ef9e5b4a8..0000000000 --- a/packages/plugins/src/menu/ImportIEDs.ts +++ /dev/null @@ -1,589 +0,0 @@ -import { - css, - html, - LitElement, - property, - query, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-check-list-item'; -import '@material/dialog'; -import '@material/mwc-button'; -import { Dialog } from '@material/mwc-dialog'; -import { List } from '@material/mwc-list'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { find, identity, isPublic } from '@openscd/open-scd/src/foundation.js'; - -import { createElement } from '@openscd/xml'; - -import { - SimpleAction, - newActionEvent, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history'; - -function uniqueTemplateIedName(doc: XMLDocument, ied: Element): string { - const [manufacturer, type] = ['manufacturer', 'type'].map(attr => - ied.getAttribute(attr)?.replace(/[^A-Za-z0-9_]/g, '') - ); - const nameCore = - manufacturer || type - ? `${manufacturer ?? ''}${type ? '_' + type : ''}` - : 'TEMPLATE_IED'; - - const siblingNames = Array.from(doc.querySelectorAll('IED')) - .filter(isPublic) - .map(child => child.getAttribute('name') ?? child.tagName); - if (!siblingNames.length) return nameCore + '_001'; - - let newName = ''; - for (let i = 0; i < siblingNames.length + 1; i++) { - const newDigit = (i + 1).toString().padStart(3, '0'); - newName = nameCore + '_' + newDigit; - - if (!siblingNames.includes(newName)) return newName; - } - - return newName; -} - -/** - * Transfer namespaces from one element to another - * @param destElement - Element to transfer namespaces to - * @param sourceElement - Element to transfer namespaces from - */ -function updateNamespaces(destElement: Element, sourceElement: Element) { - Array.prototype.slice - .call(sourceElement.attributes) - .filter(attr => attr.name.startsWith('xmlns:')) - .filter(attr => !destElement.hasAttribute(attr.name)) - .forEach(attr => { - destElement.setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - attr.name, - attr.value - ); - }); -} - -function getSubNetwork(elements: Element[], element: Element): Element { - const existElement = elements.find( - item => item.getAttribute('name') === element.getAttribute('name') - ); - return existElement ? existElement : element.cloneNode(false); -} - -function addCommunicationElements( - ied: Element, - doc: XMLDocument -): SimpleAction[] { - const actions = []; - - const oldCommunicationElement = doc.querySelector(':root > Communication'); - - const communication = oldCommunicationElement - ? oldCommunicationElement - : createElement(doc, 'Communication', {}); - - if (!oldCommunicationElement) - actions.push({ - new: { - parent: doc.querySelector(':root')!, - element: communication, - }, - }); - - const connectedAPs = Array.from( - ied.ownerDocument.querySelectorAll( - `:root > Communication > SubNetwork > ConnectedAP[iedName="${ied.getAttribute( - 'name' - )}"]` - ) - ); - - const createdSubNetworks: Element[] = []; - - connectedAPs.forEach(connectedAP => { - const newSubNetwork = connectedAP.parentElement!; - const oldSubNetworkMatch = communication.querySelector( - `:root > Communication > SubNetwork[name="${newSubNetwork.getAttribute( - 'name' - )}"]` - ); - - const subNetwork = oldSubNetworkMatch - ? oldSubNetworkMatch - : getSubNetwork(createdSubNetworks, newSubNetwork); - const element = connectedAP.cloneNode(true); - - if (!oldSubNetworkMatch && !createdSubNetworks.includes(subNetwork)) { - actions.push({ - new: { - parent: communication, - element: subNetwork, - }, - }); - createdSubNetworks.push(subNetwork); - } - - actions.push({ - new: { - parent: subNetwork, - element, - }, - }); - }); - - return actions; -} - -function hasConnectionToIed(type: Element, ied: Element): boolean { - const data: Element = type.parentElement!; - const id = type.getAttribute('id'); - - if (!data || !id) return false; - - if (type.tagName === 'EnumType') - return Array.from( - data.querySelectorAll( - `DOType > DA[type="${id}"],DAType > BDA[type="${id}"]` - ) - ).some(typeChild => hasConnectionToIed(typeChild.parentElement!, ied)); - - if (type.tagName === 'DAType') - return Array.from( - data.querySelectorAll( - `DOType > DA[type="${id}"],DAType > BDA[type="${id}"]` - ) - ).some(typeChild => hasConnectionToIed(typeChild.parentElement!, ied)); - - if (type.tagName === 'DOType') - return Array.from( - data.querySelectorAll( - `LNodeType > DO[type="${id}"], DOType > SDO[type="${id}"]` - ) - ).some(typeChild => hasConnectionToIed(typeChild.parentElement!, ied)); - - return Array.from(ied.getElementsByTagName('LN0')) - .concat(Array.from(ied.getElementsByTagName('LN'))) - .some(anyln => anyln.getAttribute('lnType') === id); -} - -function addEnumType( - ied: Element, - enumType: Element, - parent: Element -): SimpleAction | undefined { - if (!hasConnectionToIed(enumType, ied)) return; - - const existEnumType = parent.querySelector( - `EnumType[id="${enumType.getAttribute('id')}"]` - ); - if (existEnumType && enumType.isEqualNode(existEnumType)) return; - - if (existEnumType) { - // There is an `id` conflict in the project that must be resolved by - // concatenating the IED name with the id - const data: Element = enumType.parentElement!; - const idOld = enumType.getAttribute('id'); - const idNew = ied.getAttribute('name')! + idOld; - enumType.setAttribute('id', idNew); - - data - .querySelectorAll( - `DOType > DA[type="${idOld}"],DAType > BDA[type="${idOld}"]` - ) - .forEach(type => type.setAttribute('type', idNew)); - } - - return { - new: { - parent, - element: enumType, - }, - }; -} - -function addDAType( - ied: Element, - daType: Element, - parent: Element -): SimpleAction | undefined { - if (!hasConnectionToIed(daType, ied)) return; - - const existDAType = parent.querySelector( - `DAType[id="${daType.getAttribute('id')}"]` - ); - if (existDAType && daType.isEqualNode(existDAType)) return; - - if (existDAType) { - // There is an `id` conflict in the project that must be resolved by - // concatenating the IED name with the id - const data: Element | null = daType.parentElement!; - const idOld = daType.getAttribute('id'); - const idNew = ied.getAttribute('name')! + idOld; - daType.setAttribute('id', idNew); - - data - .querySelectorAll( - `DOType > DA[type="${idOld}"],DAType > BDA[type="${idOld}"]` - ) - .forEach(type => type.setAttribute('type', idNew)); - } - - return { - new: { - parent, - element: daType, - }, - }; -} - -function addDOType( - ied: Element, - doType: Element, - parent: Element -): SimpleAction | undefined { - if (!hasConnectionToIed(doType, ied)) return; - - const existDOType = parent.querySelector( - `DOType[id="${doType.getAttribute('id')}"]` - ); - if (existDOType && doType.isEqualNode(existDOType)) return; - - if (existDOType) { - // There is an `id` conflict in the project that must be resolved by - // concatenating the IED name with the id - const data: Element = doType.parentElement!; - const idOld = doType.getAttribute('id'); - const idNew = ied.getAttribute('name')! + idOld; - doType.setAttribute('id', idNew); - - data - .querySelectorAll( - `LNodeType > DO[type="${idOld}"], DOType > SDO[type="${idOld}"]` - ) - .forEach(type => type.setAttribute('type', idNew)); - } - - return { - new: { - parent, - element: doType, - }, - }; -} - -function addLNodeType( - ied: Element, - lNodeType: Element, - parent: Element -): SimpleAction | undefined { - if (!hasConnectionToIed(lNodeType, ied)) return; - - const existLNodeType = parent.querySelector( - `LNodeType[id="${lNodeType.getAttribute('id')}"]` - ); - if (existLNodeType && lNodeType.isEqualNode(existLNodeType)) return; - - if (existLNodeType) { - // There is an `id` conflict in the project that must be resolved by - // concatenating the IED name with the id - const idOld = lNodeType.getAttribute('id')!; - const idNew = ied.getAttribute('name')!.concat(idOld); - lNodeType.setAttribute('id', idNew); - - Array.from( - ied.querySelectorAll(`LN0[lnType="${idOld}"],LN[lnType="${idOld}"]`) - ) - .filter(isPublic) - .forEach(ln => ln.setAttribute('lnType', idNew)); - } - - return { - new: { - parent, - element: lNodeType, - }, - }; -} - -function addDataTypeTemplates(ied: Element, doc: XMLDocument): SimpleAction[] { - const actions: (SimpleAction | undefined)[] = []; - - const dataTypeTemplates = doc.querySelector(':root > DataTypeTemplates') - ? doc.querySelector(':root > DataTypeTemplates')! - : createElement(doc, 'DataTypeTemplates', {}); - - if (!dataTypeTemplates.parentElement) { - actions.push({ - new: { - parent: doc.querySelector('SCL')!, - element: dataTypeTemplates, - }, - }); - } - - ied.ownerDocument - .querySelectorAll(':root > DataTypeTemplates > LNodeType') - .forEach(lNodeType => - actions.push(addLNodeType(ied, lNodeType, dataTypeTemplates!)) - ); - - ied.ownerDocument - .querySelectorAll(':root > DataTypeTemplates > DOType') - .forEach(doType => - actions.push(addDOType(ied, doType, dataTypeTemplates!)) - ); - - ied.ownerDocument - .querySelectorAll(':root > DataTypeTemplates > DAType') - .forEach(daType => - actions.push(addDAType(ied, daType, dataTypeTemplates!)) - ); - - ied.ownerDocument - .querySelectorAll(':root > DataTypeTemplates > EnumType') - .forEach(enumType => - actions.push(addEnumType(ied, enumType, dataTypeTemplates!)) - ); - - return actions.filter(item => item !== undefined); -} - -function isIedNameUnique(ied: Element, doc: Document): boolean { - const existingIedNames = Array.from(doc.querySelectorAll(':root > IED')).map( - ied => ied.getAttribute('name')! - ); - const importedIedName = ied.getAttribute('name')!; - - if (existingIedNames.includes(importedIedName)) return false; - - return true; -} - -export default class ImportingIedPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @state() - iedSelection: TemplateResult[] = []; - - @query('#importied-plugin-input') pluginFileUI!: HTMLInputElement; - @query('mwc-dialog') dialog!: Dialog; - - async run(): Promise { - this.iedSelection = []; - this.pluginFileUI.click(); - } - - async docUpdate(): Promise { - await this.updateComplete; - } - - private importIED(ied: Element): void { - if (ied.getAttribute('name') === 'TEMPLATE') { - const newIedName = uniqueTemplateIedName(this.doc, ied); - - ied.setAttribute('name', newIedName); - - Array.from( - ied.ownerDocument.querySelectorAll( - ':root > Communication > SubNetwork > ConnectedAP[iedName="TEMPLATE"]' - ) - ).forEach(connectedAp => connectedAp.setAttribute('iedName', newIedName)); - } - - if (!isIedNameUnique(ied, this.doc)) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('import.log.nouniqueied', { - name: ied.getAttribute('name')!, - }), - }) - ); - return; - } - - // This doesn't provide redo/undo capability as it is not using the Editing - // action API. To use it would require us to cache the full SCL file in - // OpenSCD as it is now which could use significant memory. - - // TODO: In open-scd core update this to allow including in undo/redo. - updateNamespaces( - this.doc.documentElement, - ied.ownerDocument.documentElement - ); - - const dataTypeTemplateActions = addDataTypeTemplates(ied, this.doc); - const communicationActions = addCommunicationElements(ied, this.doc); - const actions = communicationActions.concat(dataTypeTemplateActions); - actions.push({ - new: { - parent: this.doc!.querySelector(':root')!, - element: ied, - }, - }); - - this.dispatchEvent( - newActionEvent({ - title: get('editing.import', { name: ied.getAttribute('name')! }), - actions, - }) - ); - } - - private async importIEDs( - importDoc: XMLDocument, - fileName: string - ): Promise { - const documentDialog: Dialog = this.shadowRoot!.querySelector( - `mwc-dialog[data-file="${fileName}"]` - )!; - - const selectedItems = ( - (documentDialog.querySelector('filtered-list')).selected - ); - - const ieds = selectedItems - .map(item => { - return find(importDoc, 'IED', item.value); - }) - .filter(ied => ied) as Element[]; - - documentDialog.close(); - - for (const ied of ieds) { - this.importIED(ied); - await this.docUpdate(); - } - } - - async prepareImport(importDoc: XMLDocument, fileName: string): Promise { - if (!importDoc) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('import.log.loaderror'), - }) - ); - return; - } - - if (importDoc.querySelector('parsererror')) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('import.log.parsererror'), - }) - ); - return; - } - - const ieds = Array.from(importDoc.querySelectorAll(':root > IED')); - if (ieds.length === 0) { - this.dispatchEvent( - newLogEvent({ - kind: 'error', - title: get('import.log.missingied'), - }) - ); - return; - } - - if (ieds.length === 1) { - this.importIED(ieds[0]); - return await this.docUpdate(); - } - - this.buildIedSelection(importDoc, fileName); - await this.requestUpdate(); - const dialog = ( - this.shadowRoot!.querySelector(`mwc-dialog[data-file="${fileName}"]`) - ); - dialog.show(); - - // await closing of dialog - await new Promise(resolve => { - dialog.addEventListener('closed', function onClosed(evt) { - evt.target?.removeEventListener('closed', onClosed); - resolve(); - }); - }); - } - - /** Loads the file `event.target.files[0]` into [[`src`]] as a `blob:...`. */ - protected async onLoadFiles(event: Event): Promise { - const files = Array.from( - (event.target)?.files ?? [] - ); - - const promises = files.map(file => { - return { - text: file - .text() - .then(text => - new DOMParser().parseFromString(text, 'application/xml') - ), - name: file.name, - }; - }); - - for await (const file of promises) { - await this.prepareImport(await file.text, file.name); - } - } - - protected renderInput(): TemplateResult { - return html` { - this.onLoadFiles(event); - (event.target).value = ''; - }} id="importied-plugin-input" accept=".sed,.scd,.ssd,.isd,.iid,.cid,.icd" type="file">`; - } - - protected buildIedSelection(importDoc: XMLDocument, fileName: string): void { - this.iedSelection.push(html` - - ${Array.from(importDoc?.querySelectorAll(':root > IED') ?? []).map( - ied => - html`${ied.getAttribute('name')}` - )} - - - - this.importIEDs(importDoc, fileName)} - > - `); - } - - render(): TemplateResult { - return html`${this.iedSelection}${this.renderInput()}`; - } - - static styles = css` - input { - width: 0; - height: 0; - opacity: 0; - } - `; -} diff --git a/packages/plugins/src/menu/Merge.ts b/packages/plugins/src/menu/Merge.ts deleted file mode 100644 index c898c7ff5f..0000000000 --- a/packages/plugins/src/menu/Merge.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { css, html, LitElement, query, TemplateResult } from 'lit-element'; - -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { mergeWizard } from '@openscd/open-scd/src/wizards.js'; - -export default class MergePlugin extends LitElement { - doc!: XMLDocument; - - @query('#merge-plugin-input') pluginFileUI!: HTMLInputElement; - - mergeDoc(event: Event): void { - const file = - (event.target)?.files?.item(0) ?? false; - if (file) - file.text().then(text => { - const doc = new DOMParser().parseFromString(text, 'application/xml'); - this.dispatchEvent( - newWizardEvent( - mergeWizard(this.doc.documentElement, doc.documentElement) - ) - ); - }); - this.pluginFileUI.onchange = null; - } - - async run(): Promise { - this.pluginFileUI.click(); - } - - render(): TemplateResult { - return html` - ((event.target).value = '')} @change=${ - this.mergeDoc - } id="merge-plugin-input" accept=".sed,.scd,.ssd,.isd,.iid,.cid,.icd" type="file">`; - } - - static styles = css` - input { - width: 0; - height: 0; - opacity: 0; - } - `; -} diff --git a/packages/plugins/src/menu/NewProject.ts b/packages/plugins/src/menu/NewProject.ts deleted file mode 100644 index 042d1dd963..0000000000 --- a/packages/plugins/src/menu/NewProject.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { html, LitElement } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list'; -import '@material/mwc-list/mwc-radio-list-item'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { - newWizardEvent, - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { newOpenDocEvent } from '@openscd/core/foundation/deprecated/open-event.js'; -import { EditorAction } from '@openscd/core/foundation/deprecated/editor.js'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history.js'; -import { - newEmptySCD, - SupportedVersion, -} from '@openscd/open-scd/src/schemas.js'; - -export default class NewProjectPlugin extends LitElement { - - private createNewProject( - inputs: WizardInputElement[], - wizard: Element - ): EditorAction[] { - - let docName = inputs[0].value ?? '' - - const acceptedFileExtension = ['.ssd', '.scd','.fsd']; - const isValidFileFormat = acceptedFileExtension.some((extension) => { - return inputs[0].value?.endsWith(extension); - }) - - if(!isValidFileFormat) { - docName = docName + '.scd'; - } - - const version = ( - (wizard.shadowRoot!.querySelector('mwc-list')!.selected) - .value - ); - - this.dispatchEvent(newLogEvent({ kind: 'reset' })); - this.dispatchEvent( - newOpenDocEvent(newEmptySCD(docName.slice(0, -4), version), docName) - ); - - return [{ actions: [], title: '', derived: true }]; - } - private newProjectWizard(): Wizard { - return [ - { - title: get('menu.new'), - primary: { - icon: 'create_new_folder', - label: get('create'), - action: (inputs, wizard) => this.createNewProject(inputs, wizard), - }, - content: [ - html` - - Edition 1 (Schema 1.7) - Edition 2 (Schema 3.1) - Edition 2.1 (2007B4) - `, - ], - }, - ]; - } - - async run(): Promise { - this.dispatchEvent(newWizardEvent(this.newProjectWizard())); - } -} diff --git a/packages/plugins/src/menu/OpenProject.ts b/packages/plugins/src/menu/OpenProject.ts deleted file mode 100644 index 81a12e569a..0000000000 --- a/packages/plugins/src/menu/OpenProject.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { css, html, LitElement, query, TemplateResult } from 'lit-element'; - -import { newOpenDocEvent } from '@openscd/core/foundation/deprecated/open-event.js'; -import { newLogEvent } from '@openscd/core/foundation/deprecated/history.js'; - -export default class OpenProjectPlugin extends LitElement { - @query('#open-plugin-input') pluginFileUI!: HTMLInputElement; - - async openDoc(event: Event): Promise { - const file = - (event.target)?.files?.item(0) ?? false; - if (!file) return; - - const text = await file.text(); - const docName = file.name; - const doc = new DOMParser().parseFromString(text, 'application/xml'); - - this.dispatchEvent(newLogEvent({ kind: 'reset' })); - this.dispatchEvent(newOpenDocEvent(doc, docName)); - this.pluginFileUI.onchange = null; - this.closeMenu(); - } - - private async closeMenu() { - this.dispatchEvent( - new CustomEvent('close-drawer', { - bubbles: true, - composed: true, // to traverse shadow DOM boundaries src: https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/ - }) - ); - } - - async run(): Promise { - this.pluginFileUI.click(); - } - - render(): TemplateResult { - return html` - ((event.target).value = '')} @change=${ - this.openDoc - } id="open-plugin-input" accept=".sed,.scd,.ssd,.isd,.iid,.cid,.icd" type="file">`; - } - - static styles = css` - input { - width: 0; - height: 0; - opacity: 0; - } - `; -} diff --git a/packages/plugins/src/menu/SaveProject.ts b/packages/plugins/src/menu/SaveProject.ts deleted file mode 100644 index 505e2e7388..0000000000 --- a/packages/plugins/src/menu/SaveProject.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { LitElement, property } from 'lit-element'; - -function formatXml(xml: string, tab?: string) { - let formatted = '', - indent = ''; - - if (!tab) tab = '\t'; - xml.split(/>\s*\r\n'; - if (node.match(/^]*[^/]$/)) indent += tab; - }); - return formatted.substring(1, formatted.length - 3); -} - -export default class SaveProjectPlugin extends LitElement { - @property() doc!: XMLDocument; - @property() docName!: string; - - async run(): Promise { - if (this.doc) { - let documentAsString = formatXml( - new XMLSerializer().serializeToString(this.doc) - ); - - // Add XML declaration/prolog if it's been stripped - // TODO: This can be removed once the improved OpenSCD core edit API is present - documentAsString = documentAsString.startsWith('' + '\n' + documentAsString; - - const blob = new Blob([documentAsString], { - type: 'application/xml', - }); - - const a = document.createElement('a'); - a.download = this.docName; - a.href = URL.createObjectURL(blob); - a.dataset.downloadurl = ['application/xml', a.download, a.href].join(':'); - a.style.display = 'none'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - setTimeout(function () { - URL.revokeObjectURL(a.href); - }, 5000); - } - } -} diff --git a/packages/plugins/src/menu/SclHistory.ts b/packages/plugins/src/menu/SclHistory.ts deleted file mode 100644 index ee5a3dd337..0000000000 --- a/packages/plugins/src/menu/SclHistory.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { - html, - css, - property, - query, - TemplateResult, - LitElement, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; -import { Dialog } from '@material/mwc-dialog'; - -export default class SclHistoryPlugin extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - - @query('#historyLog') historyLog!: Dialog; - - private createMessage( - who: string | null, - why: string | null - ): string | undefined { - let message = who; - if (message !== null && why !== null) { - message += ' : ' + why; - } else if (why !== null) { - message = why; - } - return message ?? undefined; - } - - get sclHistory(): Element[] { - if (this.doc) { - return Array.from( - this.doc.querySelectorAll(':root > Header > History > Hitem') - ); - } - return []; - } - - async run(): Promise { - this.historyLog.open = true; - } - - renderSclHistoryEntry(element: Element): TemplateResult { - const message = this.createMessage( - element.getAttribute('who'), - element.getAttribute('why') - ); - const title = element.getAttribute('what'); - return html` - - - ${element.getAttribute('when')} - ${title} - ${message} - `; - } - - private renderSclHistory(): TemplateResult[] | TemplateResult { - if (this.sclHistory.length > 0) - return this.sclHistory - .slice() - .reverse() - .map(this.renderSclHistoryEntry, this); - else - return html` - ${get('history.noEntries')} - `; - } - - render(): TemplateResult { - return html` - ${this.renderSclHistory()} - ${get('close')} - `; - } - - static styles = css` - .sclHistory { - display: flex; - } - #historyLog { - --mdc-dialog-min-width: 92vw; - } - abbr { - text-decoration: none; - } - `; -} diff --git a/packages/plugins/src/menu/SubscriberInfo.ts b/packages/plugins/src/menu/SubscriberInfo.ts deleted file mode 100644 index e500a3fcc3..0000000000 --- a/packages/plugins/src/menu/SubscriberInfo.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { LitElement } from 'lit-element'; -import { get } from 'lit-translate'; -import { getVersion } from '@openscd/open-scd/src/foundation.js'; - -import { createElement } from '@openscd/xml'; - -import { - newActionEvent, - SimpleAction, -} from '@openscd/core/foundation/deprecated/editor.js'; - -function getElementIndexOf(list: (Element | null)[], match: Element): number { - for (let i = 0; list.length; i++) if (list[i]?.isEqualNode(match)) return i; - - return -1; -} - -function addIEDName(extRef: Element, gseControl: Element): Element | null { - const [ied, accPoint, lDevice, ln, ln0] = [ - 'IED', - 'AccessPoint', - 'LDevice', - 'LN', - 'LN0', - ].map(element => extRef.closest(element)); - const anyln = ln ? ln : ln0; - - if ( - getVersion(extRef) === '2007' && - Array.from(gseControl.getElementsByTagName('IEDName')) - .filter(item => !item.closest('Private')) - .filter( - iedName => - iedName.innerHTML === ied?.getAttribute('name') && - (iedName.getAttribute('apRef') ?? '') === - (accPoint?.getAttribute('name') ?? '') && - (iedName.getAttribute('ldInst') ?? '') === - (lDevice?.getAttribute('inst') ?? '') && - (iedName.getAttribute('prefix') ?? '') === - (anyln?.getAttribute('prefix') ?? '') && - (iedName.getAttribute('lnClass') ?? '') === - (anyln?.getAttribute('lnClass') ?? '') && - (iedName.getAttribute('lnInst') ?? '') === - (anyln?.getAttribute('inst') ?? '') - ).length === 0 - ) { - const iedName: Element = createElement( - gseControl.ownerDocument, - 'IEDName', - { - apRef: accPoint?.getAttribute('name') ?? '', - ldInst: lDevice?.getAttribute('inst') ?? '', - prefix: anyln?.getAttribute('prefix') ?? '', - lnClass: anyln?.getAttribute('lnClass') ?? '', - lnInst: anyln?.getAttribute('inst') || null, - } - ); - iedName.innerHTML = ied?.getAttribute('name')!; - - return iedName; - } - - if ( - Array.from(gseControl.getElementsByTagName('IEDName')) - .filter(item => !item.closest('Private')) - .filter(iedName => iedName.innerHTML === ied?.getAttribute('name')) - .length === 0 - ) { - const iedName: Element = createElement( - gseControl.ownerDocument, - 'IEDName', - {} - ); - iedName.innerHTML = ied?.getAttribute('name')!; - - return iedName; - } - - return null; -} - -function getDestination(data: Element, doc: Document): Element[] { - return Array.from(doc.getElementsByTagName('ExtRef')) - .filter(item => !item.closest('Private')) - .filter( - extRef => - (extRef.getAttribute('iedName') ?? '') === - (data.closest('IED')?.getAttribute('name') ?? '') && - (extRef.getAttribute('ldInst') ?? '') === - (data.getAttribute('ldInst') ?? '') && - (extRef.getAttribute('prefix') ?? '') === - (data.getAttribute('prefix') ?? '') && - (extRef.getAttribute('lnClass') ?? '') === - (data.getAttribute('lnClass') ?? '') && - (extRef.getAttribute('lnInst') ?? '') === - (data.getAttribute('lnInst') ?? '') && - (extRef.getAttribute('doName') ?? '') === - (data.getAttribute('doName') ?? '') && - (extRef.getAttribute('daName') ?? '') === - (data.getAttribute('daName') ?? '') - ); -} - -export function createMissingIEDNameSubscriberInfo( - doc: Document -): SimpleAction[] { - const controlList = Array.from( - doc.querySelectorAll( - ':root > IED > AccessPoint > Server > LDevice > LN0 > GSEControl,' + - ':root > IED > AccessPoint > Server > LDevice > LN0 > SampledValueControl' - ) - ); - - const simpleAction: SimpleAction[] = []; - controlList.forEach(controlBlock => { - if (!controlBlock.getAttribute('datSet') || !controlBlock.parentElement) - return simpleAction; - - const ln0: Element = controlBlock.parentElement; - const dataList: Element[] = Array.from( - ln0.querySelectorAll( - `:root > IED > AccessPoint > Server > LDevice > LN0 > DataSet[name="${controlBlock.getAttribute( - 'datSet' - )}"] > FCDA` - ) - ); - - const destList: Element[] = dataList - .flatMap(data => getDestination(data, doc)) - .filter(dest => dest !== null) - .filter((v, i, a) => a.indexOf(v) === i); - - const iedNameList: (Element | null)[] = destList - .map(dest => addIEDName(dest, controlBlock)) - .filter(iedName => iedName !== null) - .filter((v, i, a) => getElementIndexOf(a, v!) === i); - - iedNameList.forEach(iedName => { - simpleAction.push({ - new: { - parent: controlBlock, - element: iedName!, - }, - }); - }); - }); - - return simpleAction; -} - -export default class SubscriberInfoPlugin extends LitElement { - doc!: XMLDocument; - - async run(): Promise { - const actions: SimpleAction[] = createMissingIEDNameSubscriberInfo( - this.doc! - ); - - if (!actions.length) - throw new Error( - get('subscriber.description') + get('subscriber.nonewitems') - ); - - this.dispatchEvent( - newActionEvent({ - title: - get('subscriber.description') + - get('subscriber.message', { - updatenumber: actions.length, - }), - actions: actions, - }) - ); - - return; - } -} diff --git a/packages/plugins/src/menu/UpdateDescriptionABB.ts b/packages/plugins/src/menu/UpdateDescriptionABB.ts deleted file mode 100644 index a67c56617a..0000000000 --- a/packages/plugins/src/menu/UpdateDescriptionABB.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { html, LitElement } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-check-list-item'; -import { List } from '@material/mwc-list'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - find, - identity, - isPublic, - newWizardEvent, - SCLTag, - Wizard, - WizardAction, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement } from '@openscd/xml'; - -interface addDescItem { - desc: string; - tag: SCLTag; - identity: string | number; -} - -function addDescriptionAction(doc: XMLDocument): WizardActor { - return ( - _: WizardInputElement[], - wizard: Element, - list: List | null | undefined - ): WizardAction[] => { - const selectedItems = list!.selected; - - const actions = selectedItems.map(item => { - const desc = (item.querySelector('span')).textContent; - const [tag, identity] = item.value.split(' | '); - - const oldElement = find(doc, tag, identity)!; - const newElement = cloneElement(oldElement, { desc }); - return { old: { element: oldElement }, new: { element: newElement } }; - }); - - return [ - { - title: get('updatedesc.abb'), - actions, - }, - ]; - }; -} - -function createLogWizard(doc: XMLDocument, items: addDescItem[]): Wizard { - return [ - { - title: get('wizard.title.add', { tagName: 'desc' }), - primary: { - label: get('save'), - icon: 'save', - action: addDescriptionAction(doc), - }, - content: [ - html`${Array.from( - items.map( - item => - html`${item.desc}${item.tag + ' | ' + item.identity}` - ) - )}`, - ], - }, - ]; -} - -function addDescriptionToABB(ied: Element): addDescItem[] { - return Array.from(ied.getElementsByTagName('ExtRef')) - .filter(element => isPublic(element)) - .filter(extRef => extRef.getAttribute('intAddr')) - .map(extRef => { - const intAddr = extRef.getAttribute('intAddr')!; - const internalMapping = intAddr.split(',')[3]; //this might change as is vendor dependant!! - const oldDesc = extRef.getAttribute('desc'); - const newDesc = oldDesc - ? oldDesc + '-' + internalMapping - : internalMapping; - - return { - desc: newDesc, - tag: 'ExtRef', - identity: identity(extRef), - }; - }); -} - -/** Plug-in that enriched ExtRefs desc attribute based on intAddr attribute (ABB)*/ -export default class UpdateDescriptionAbb extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - doc!: XMLDocument; - - /** Entry point for this plug-in */ - async run(): Promise { - const items = Array.from(this.doc.querySelectorAll(':root > IED')).flatMap( - ied => addDescriptionToABB(ied) - ); - - this.dispatchEvent(newWizardEvent(createLogWizard(this.doc, items))); - } -} diff --git a/packages/plugins/src/menu/UpdateDescriptionSEL.ts b/packages/plugins/src/menu/UpdateDescriptionSEL.ts deleted file mode 100644 index 374476b716..0000000000 --- a/packages/plugins/src/menu/UpdateDescriptionSEL.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { css, html, LitElement, query, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-list/mwc-check-list-item'; -import { List } from '@material/mwc-list'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { - find, - identity, - isPublic, - newWizardEvent, - SCLTag, - Wizard, - WizardAction, - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; - -import { cloneElement } from '@openscd/xml'; - -interface SignalDescription { - desc: string; - tag: SCLTag; - identity: string | number; -} - -function addDescriptionToSEL( - ied: Element, - signalList: string[][] -): SignalDescription[] { - const iedName = ied.getAttribute('name'); - const manufacturer = ied.getAttribute('manufacturer'); - if (!iedName || manufacturer !== 'SEL') return []; - - return Array.from(ied.getElementsByTagName('DAI')) - .filter(element => isPublic(element)) - .filter(dai => { - const datasrc = dai.getAttributeNS( - 'http://www.selinc.com/2006/61850', - 'datasrc' - ); - return datasrc?.startsWith('db:'); - }) - .map(dai => { - //the next lines are vendor dependant!! - const datasrc = dai.getAttributeNS( - 'http://www.selinc.com/2006/61850', - 'datasrc' - ); - - const tag = datasrc ? datasrc.replace('db:', '') : null; - const desc = - signalList.find(row => row[2] === tag && row[1] === iedName)?.[0] ?? - null; - - return desc ? { desc, tag: 'DAI', identity: identity(dai) } : null; - }) - .filter(signalDescription => signalDescription); -} - -function addDescriptionAction(doc: XMLDocument): WizardActor { - return ( - _: WizardInputElement[], - wizard: Element, - list: List | null | undefined - ): WizardAction[] => { - const selectedItems = list!.selected; - - const actions = selectedItems.map(item => { - const desc = (item.querySelector('span')).textContent; - const [tag, identity] = item.value.split(' | '); - - const oldElement = find(doc, tag, identity)!; - const newElement = cloneElement(oldElement, { desc }); - return { old: { element: oldElement }, new: { element: newElement } }; - }); - - return [ - { - title: get('updatedesc.sel'), - actions, - }, - ]; - }; -} - -function createLogWizard(doc: XMLDocument, items: SignalDescription[]): Wizard { - return [ - { - title: get('wizard.title.add', { tagName: 'desc' }), - primary: { - label: get('save'), - icon: 'save', - action: addDescriptionAction(doc), - }, - content: [ - html`${Array.from( - items.map( - item => - html`${item.desc}${item.tag + ' | ' + item.identity}` - ) - )}`, - ], - }, - ]; -} - -function parseCsv(str: string, delimiter: ',' | ';'): string[][] { - // predefined for later use - const quoteChar = '"', - escapeChar = '\\'; - - const entries: string[][] = []; - let isInsideQuote = false; - - // Iterate over each character, keep track of current row and column (of the returned array) - for (let row = 0, col = 0, char = 0; char < str.length; char++) { - const currentChar = str[char]; - const nextChar = str[char + 1]; - - entries[row] = entries[row] || []; - entries[row][col] = entries[row][col] || ''; - - //Ignore escape character - if (currentChar === escapeChar) { - entries[row][col] += nextChar; - ++char; - continue; - } - - // Check for quoted characters. Do not miss-interpret delimiter within field - if (currentChar === quoteChar) { - isInsideQuote = !isInsideQuote; - continue; - } - - if (!isInsideQuote) { - if (currentChar === delimiter) { - ++col; - entries[row][col] = ''; - continue; - } - - if (currentChar === '\n' || currentChar === '\r') { - ++row; - col = 0; - - // Skip the next character for CRLF - if (currentChar === '\r' && nextChar === '\n') ++char; - - continue; - } - } - - entries[row][col] += currentChar; - } - - return entries; -} - -function getGuessDelimiter(csvString: string): ';' | ',' { - let numberComma = 0, - numberSemicolon = 0; - - const quoteChar = '"'; - - let isInsideQuote = false; - for (const currentChar of csvString) { - // Check for quoted characters. Do not miss-interpret delimiter within field - if (currentChar === quoteChar) { - isInsideQuote = !isInsideQuote; - continue; - } - - if (!isInsideQuote) { - if (currentChar === ';') { - numberSemicolon++; - continue; - } - - if (currentChar === ',') { - numberComma++; - continue; - } - } - } - - return numberComma > numberSemicolon ? ',' : ';'; -} - -/** - * Plug-in that enriches the desc attribute in SEL type IED elements based on a signal list - * The signal list must be a ; or , separated CSV file with 3 columns. - * 1st column: signal name - * 2nd column: IED name - * 3rd column: identifier from the SEL namespace excluding the prefix of "db:", - * similar to relay word bit name (RWB), e.g. SV24T, 51P1T, IN203 - */ -export default class UpdateDescriptionSel extends LitElement { - /** The document being edited as provided to plugins by [[`OpenSCD`]]. */ - doc!: XMLDocument; - - @query('#plugin-input') pluginFileUI!: HTMLInputElement; - - processSignalList(csvString: string): void { - const signalList = parseCsv(csvString, getGuessDelimiter(csvString)); - - const items = Array.from(this.doc.querySelectorAll('IED')) - .filter(ied => isPublic(ied)) - .flatMap(ied => addDescriptionToSEL(ied, signalList)); - - this.dispatchEvent(newWizardEvent(createLogWizard(this.doc, items))); - } - - private async onFileInput(e: Event): Promise { - const file = (e.target)?.files?.item(0) ?? false; - if (!file) return; - - this.processSignalList(await file.text()); - } - - /** Entry point for this plug-in */ - async run(): Promise { - this.pluginFileUI.click(); - } - - render(): TemplateResult { - return html` - ((event.target).value = '')} @change=${(e: Event) => - this.onFileInput( - e - )} id="plugin-input" accept=".csv" type="file">`; - } - - static styles = css` - input { - width: 0; - height: 0; - opacity: 0; - } - `; -} diff --git a/packages/plugins/src/menu/UpdateSubstation.ts b/packages/plugins/src/menu/UpdateSubstation.ts deleted file mode 100644 index ec080f8bd4..0000000000 --- a/packages/plugins/src/menu/UpdateSubstation.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { css, html, LitElement, query, TemplateResult } from 'lit-element'; -import { get } from 'lit-translate'; - -import { - crossProduct, - find, - identity, - newWizardEvent, - SCLTag, - tags, -} from '@openscd/open-scd/src/foundation.js'; -import { Diff, mergeWizard } from '@openscd/open-scd/src/wizards.js'; - -export function isValidReference( - doc: XMLDocument, - identity: string | number -): boolean { - if (typeof identity !== 'string') return false; - const [iedName, ldInst, prefix, lnClass, lnInst] = identity.split(/[ /]/); - - if (!iedName || !lnClass) return false; - - if (ldInst === '(Client)') { - const [ - iedNameSelectors, - prefixSelectors, - lnClassSelectors, - lnInstSelectors, - ] = [ - [`IED[name="${iedName}"]`], - prefix ? [`[prefix="${prefix}"]`] : [':not([prefix])', '[prefix=""]'], - [`LN[lnClass="${lnClass}"]`], - lnInst ? [`[inst="${lnInst}"]`] : [':not([inst])', '[inst=""]'], - ]; - - return ( - doc.querySelector( - crossProduct( - iedNameSelectors, - ['>AccessPoint>'], - lnClassSelectors, - prefixSelectors, - lnInstSelectors - ) - .map(strings => strings.join('')) - .join(',') - ) !== null - ); - } - - const [ - iedNameSelectors, - ldInstSelectors, - prefixSelectors, - lnClassSelectors, - lnInstSelectors, - ] = [ - [`IED[name="${iedName}"]`], - [`LDevice[inst="${ldInst}"]`], - prefix ? [`[prefix="${prefix}"]`] : [':not([prefix])', '[prefix=""]'], - lnClass === 'LLN0' ? [`LN0`] : [`LN[lnClass="${lnClass}"]`], - lnInst ? [`[inst="${lnInst}"]`] : [':not([inst])', '[inst=""]'], - ]; - - return ( - doc.querySelector( - crossProduct( - iedNameSelectors, - [' '], - ldInstSelectors, - ['>'], - lnClassSelectors, - prefixSelectors, - lnInstSelectors - ) - .map(strings => strings.join('')) - .join(',') - ) !== null - ); -} - -export function mergeSubstation( - element: Element, - currentDoc: Document, - docWithSubstation: Document -): void { - element.dispatchEvent( - newWizardEvent( - mergeWizard( - // FIXME: doesn't work with multiple Substations! - currentDoc.documentElement, - docWithSubstation.documentElement, - { - title: get('updatesubstation.title'), - selected: (diff: Diff): boolean => - diff.theirs instanceof Element - ? diff.theirs.tagName === 'LNode' - ? find(currentDoc, 'LNode', identity(diff.theirs)) === null && - isValidReference(docWithSubstation, identity(diff.theirs)) - : diff.theirs.tagName === 'Substation' || - !tags['SCL'].children.includes(diff.theirs.tagName) - : diff.theirs !== null, - disabled: (diff: Diff): boolean => - diff.theirs instanceof Element && - diff.theirs.tagName === 'LNode' && - (find(currentDoc, 'LNode', identity(diff.theirs)) !== null || - !isValidReference(docWithSubstation, identity(diff.theirs))), - auto: (): boolean => true, - } - ) - ) - ); -} - -export default class UpdateSubstationPlugin extends LitElement { - doc!: XMLDocument; - - @query('#update-substation-plugin-input') pluginFileUI!: HTMLInputElement; - - async updateSubstation(event: Event): Promise { - const file = - (event.target)?.files?.item(0) ?? false; - if (!file) { - return; - } - const text = await file.text(); - const doc = new DOMParser().parseFromString(text, 'application/xml'); - - mergeSubstation(this, this.doc, doc); - this.pluginFileUI.onchange = null; - } - - async run(): Promise { - this.pluginFileUI.click(); - } - - render(): TemplateResult { - return html` - ((event.target).value = '')} - @change=${this.updateSubstation} - id="update-substation-plugin-input" accept=".sed,.scd,.ssd,.iid,.cid" type="file">`; - } - - static styles = css` - input { - width: 0; - height: 0; - opacity: 0; - } - `; -} diff --git a/packages/plugins/src/menu/VirtualTemplateIED.ts b/packages/plugins/src/menu/VirtualTemplateIED.ts deleted file mode 100644 index 077e567f48..0000000000 --- a/packages/plugins/src/menu/VirtualTemplateIED.ts +++ /dev/null @@ -1,338 +0,0 @@ -import { - css, - html, - LitElement, - property, - query, - queryAll, - state, - TemplateResult, -} from 'lit-element'; -import { get } from 'lit-translate'; - -import '@material/mwc-dialog'; -import '@material/mwc-list'; -import '@material/mwc-list/mwc-list-item'; -import '@material/mwc-list/mwc-check-list-item'; -import '@material/mwc-list/mwc-radio-list-item'; -import { Dialog } from '@material/mwc-dialog'; -import { CheckListItem } from '@material/mwc-list/mwc-check-list-item'; -import { Select } from '@material/mwc-select'; - -import '@openscd/open-scd/src/filtered-list.js'; -import { find, identity } from '@openscd/open-scd/src/foundation.js'; -import { getChildElementsByTagName } from '@openscd/xml'; - -import { newActionEvent } from '@openscd/core/foundation/deprecated/editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - getFunctionNamingPrefix, - getNonLeafParent, - getSpecificationIED, - getUniqueFunctionName, - LDeviceDescription, -} from './virtualtemplateied/foundation.js'; - -export type FunctionElementDescription = { - uniqueName: string; - lNodes: Element[]; - lln0?: Element; -}; - -/** converts FunctionElementDescription's to LDeviceDescription's */ -function getLDeviceDescriptions( - functions: Record, - selectedLNodes: Element[], - selectedLLN0s: string[] -): LDeviceDescription[] { - const lDeviceDescriptions: LDeviceDescription[] = []; - - Object.values(functions).forEach(functionDescription => { - if ( - functionDescription.lNodes.some(lNode => selectedLNodes.includes(lNode)) - ) { - const lLN0 = selectedLLN0s.find(selectedLLN0 => - selectedLLN0.includes(functionDescription.uniqueName) - )!; - const lnType = lLN0?.split(': ')[1]; - - lDeviceDescriptions.push({ - validLdInst: functionDescription.uniqueName, - anyLNs: [ - { prefix: null, lnClass: 'LLN0', inst: '', lnType }, - ...functionDescription.lNodes - .filter(lNode => selectedLNodes.includes(lNode)) - .map(lNode => { - return { - prefix: getFunctionNamingPrefix(lNode), - lnClass: lNode.getAttribute('lnClass')!, - inst: lNode.getAttribute('lnInst')!, - lnType: lNode.getAttribute('lnType')!, - }; - }), - ], - }); - } - }); - - return lDeviceDescriptions; -} - -/** Groups all incomming LNode's with non-leaf parent function type elements */ -function groupLNodesToFunctions( - lNodes: Element[] -): Record { - const functionElements: Record = {}; - - lNodes.forEach(lNode => { - const parentFunction = getNonLeafParent(lNode); - if (!parentFunction) return; - - if (functionElements[identity(parentFunction)]) - functionElements[identity(parentFunction)].lNodes.push(lNode); - else { - functionElements[identity(parentFunction)] = { - uniqueName: getUniqueFunctionName(parentFunction), - lNodes: [lNode], - lln0: getChildElementsByTagName(parentFunction, 'LNode').find( - lNode => lNode.getAttribute('lnClass') === 'LLN0' - ), - }; - } - }); - - return functionElements; -} - -export default class VirtualTemplateIED extends LitElement { - @property({ attribute: false }) - doc!: XMLDocument; - @property({ type: Number }) - editCount = -1; - @state() - get isValidManufacturer(): boolean { - const manufacturer = this.dialog?.querySelector( - 'wizard-textfield[label="manufacturer"]' - )!.value; - - return (manufacturer && manufacturer !== '') || false; - } - @state() - get isValidApName(): boolean { - const apName = this.dialog?.querySelector( - 'wizard-textfield[label="AccessPoint name"]' - )!.value; - - return (apName && apName !== '') || false; - } - @state() - get someItemsSelected(): boolean { - if (!this.selectedLNodeItems) return false; - return !!this.selectedLNodeItems.length; - } - @state() - get validPriparyAction(): boolean { - return ( - this.someItemsSelected && this.isValidManufacturer && this.isValidApName - ); - } - - get unreferencedLNodes(): Element[] { - return Array.from( - this.doc.querySelectorAll('LNode[iedName="None"]') - ).filter(lNode => lNode.getAttribute('lnClass') !== 'LLN0'); - } - - get lLN0s(): Element[] { - return Array.from(this.doc.querySelectorAll('LNodeType[lnClass="LLN0"]')); - } - - @query('mwc-dialog') dialog!: Dialog; - @queryAll('mwc-check-list-item[selected]') - selectedLNodeItems?: CheckListItem[]; - - async run(): Promise { - this.dialog.open = true; - } - - private onPrimaryAction( - functions: Record - ): void { - const selectedLNode = Array.from( - this.dialog.querySelectorAll( - 'mwc-check-list-item[selected]:not([disabled])' - ) ?? [] - ).map(selectedItem => find(this.doc, 'LNode', selectedItem.value)!); - if (!selectedLNode.length) return; - - const selectedLLN0s = Array.from( - this.dialog.querySelectorAlle.target).selected?.value; - const selectedBType = (( - (e.target).parentElement!.querySelector( - 'wizard-select[label="Val"]' - )! - ); - render(html`${enumVals}`, selectValOptionUI); - selectValOptionUI.requestUpdate(); -} - -function selectBType( - e: SelectedEvent, - bType: string | null, - type: string | null -): void { - const bTypeSelected = (( - (e.target).parentElement!.querySelector( - 'wizard-select[label="Val"]' - )! - ); - if (bTypeSelected === 'Enum') selectValOptionUI.style.display = ''; - else selectValOptionUI.style.display = 'none'; - - const textfieldValOptionUI = ( - (( - parent.wizardUI.dialog?.querySelector('mwc-select[label="type"]') - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add conducting equipment if name attribute is not unique', async () => { - typeSelect.value = 'CBR'; - nameField.value = 'QA1'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelectorAll( - 'VoltageLevel[name="E1"] > Bay[name="COUPLING_BAY"] > ConductingEquipment[name="QA1"]' - ).length - ).to.equal(1); - }); - it('does add conducting equipment if name attribute is unique', async () => { - typeSelect.value = 'CBR'; - nameField.value = 'QA2'; - await parent.updateComplete; - primaryAction.click(); - expect( - doc.querySelector( - 'VoltageLevel[name="E1"] > Bay[name="COUPLING_BAY"] > ConductingEquipment[name="QA2"]' - ) - ).to.exist; - }); - }); - describe('open lnode wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('bay-editor'); - - (( - element?.shadowRoot?.querySelector( - 'mwc-icon-button[icon="account_tree"]' - ) - )).click(); - await parent.updateComplete; - }); - it('opens lnode wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has two wizard pages', async () => { - expect(parent.wizardUI.dialogs.length).to.equal(2); - }); - }); - describe('move action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - let element2: BayEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`${Array.from(doc?.querySelectorAll('Bay') ?? []).map( - bay => html`` - )} - >` - ) - ); - element = parent.querySelector('bay-editor:nth-child(1)'); - element2 = parent.querySelector('bay-editor:nth-child(2)'); - }); - it('moves Bay within VoltageLevel', async () => { - expect(doc.querySelector('Bay')?.getAttribute('name')).to.equal( - 'COUPLING_BAY' - ); - (( - element2?.shadowRoot?.querySelector('mwc-icon-button[icon="forward"]') - )).click(); - await parent.updateComplete; - (element).click(); - await parent.updateComplete; - expect(doc.querySelector('Bay')?.getAttribute('name')).to.equal('Bay2'); - }); - }); - describe('remove action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('bay-editor'); - }); - it('removes Bay on clicking delete button', async () => { - expect(doc.querySelector('Bay[name="COUPLING_BAY"]')).to.exist; - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - )).click(); - await parent.updateComplete; - expect(doc.querySelector('Bay[name="COUPLING_BAY"]')).to.not.exist; - }); - }); - - describe('clone action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - let copyContentButton: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/clone/noUnusedLNode.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('bay-editor'); - await parent.updateComplete; - - copyContentButton = ( - element?.shadowRoot?.querySelector( - 'mwc-icon-button[icon="content_copy"]' - ) - ); - }); - it('duplicates Bay on clicking duplicate button', async () => { - copyContentButton.click(); - await parent.updateComplete; - expect(doc.querySelector('Bay[name="Q03')).to.exist; - }); - - it('removes all LNode elements in the copy', async () => { - expect(doc.querySelector('Bay[name="Q01"]')?.querySelector('LNode')).to - .exist; - copyContentButton.click(); - await parent.updateComplete; - expect(doc.querySelector('Bay[name="Q03"]')?.querySelector('LNode')).to - .not.exist; - }); - - it('removes all Terminal elements expect the grounding in the copy', async () => { - expect( - doc - .querySelector('Bay[name="Q01"]') - ?.querySelector('Terminal:not([cNodeName="grounded"])') - ).to.exist; - copyContentButton.click(); - await parent.updateComplete; - expect( - doc - .querySelector('Bay[name="Q03"]') - ?.querySelector('Terminal:not([cNodeName="grounded"])') - ).to.not.exist; - }); - - it('removes all ConnectivityNode elements in the copy', async () => { - expect( - doc.querySelector('Bay[name="Q01"]')?.querySelector('ConnectivityNode') - ).to.exist; - copyContentButton.click(); - await parent.updateComplete; - expect( - doc.querySelector('Bay[name="Q03"]')?.querySelector('ConnectivityNode') - ).to.not.exist; - }); - - it('keeps all ConductingEquipment elements in the copy', async () => { - copyContentButton.click(); - await parent.updateComplete; - expect( - doc - .querySelector('Bay[name="Q01"]') - ?.querySelectorAll('ConductingEquipment').length - ).to.equal( - doc - .querySelector('Bay[name="Q03"]') - ?.querySelectorAll('ConductingEquipment').length - ); - }); - }); - - describe('open create wizard for element Function', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('bay-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="Function"]') - )).click(); - await parent.requestUpdate(); - - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add Function if name attribute is not unique', async () => { - expect( - doc.querySelector('Bay[name="COUPLING_BAY"] > Function[name="bayName"]') - ).to.exist; - - nameField.value = 'bayName'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"]' - ).length - ).to.equal(1); - }); - - it('does add Function if name attribute is unique', async () => { - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="someNewFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="someNewFunction"]' - ) - ).to.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: BayEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('bay-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/bay-editor-wizarding.test.ts b/packages/plugins/test/integration/editors/substation/bay-editor-wizarding.test.ts deleted file mode 100644 index 6122dbefef..0000000000 --- a/packages/plugins/test/integration/editors/substation/bay-editor-wizarding.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../../src/editors/substation/bay-editor.js'; -import { regExp, regexString } from '../../../foundation.js'; - -describe('bay-editor wizarding integration', () => { - let doc: XMLDocument; - let parent: OscdWizards; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = await fixture( - html` - - - ` - ); - - (( - parent - ?.querySelector('bay-editor') - ?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - }); - - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - - describe('the first input element', () => { - it('edits the attribute name', async () => { - expect(parent.wizardUI.inputs[0].label).to.equal('name'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tName, 1), async name => { - parent.wizardUI.inputs[0].value = name; - await parent.updateComplete; - expect(parent.wizardUI.inputs[0].checkValidity()).to.be.true; - }) - ); - }); - }); - - describe('the second input element', () => { - it('edits the attribute desc', async () => { - expect(parent.wizardUI.inputs[1].label).to.equal('desc'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.desc), async desc => { - parent.wizardUI.inputs[1].value = desc; - await parent.updateComplete; - expect(parent.wizardUI.inputs[1].checkValidity()).to.be.true; - }) - ); - }); - }); - -}); diff --git a/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding-editing.test.ts deleted file mode 100644 index 47548dac58..0000000000 --- a/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,348 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/conducting-equipment-editor.js'; -import { ConductingEquipmentEditor } from '../../../../src/editors/substation/conducting-equipment-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: ConductingEquipmentEditor -) => Promise = ( - parent: MockWizardEditor, - element: ConductingEquipmentEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodeMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodeMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('conducting-equipment-editor wizarding editing integration', () => { - describe('edit wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - - let nameField: WizardTextField; - let descField: WizardTextField; - let secondaryAction: HTMLElement; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('conducting-equipment-editor'); - await (( - element?.shadowRoot?.querySelector('*[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - it('changes name attribute on primary action', async () => { - nameField.value = 'newName'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('ConductingEquipment')?.getAttribute('name') - ).to.equal('newName'); - }); - it('changes desc attribute on primary action', async () => { - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('ConductingEquipment')?.getAttribute('desc') - ).to.equal('newDesc'); - }); - it('deletes desc attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('ConductingEquipment')?.getAttribute('desc')).to - .be.null; - }); - }); - describe('open lnode wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('conducting-equipment-editor'); - - (( - element?.shadowRoot?.querySelector('*[icon="account_tree"]') - )).click(); - await parent.updateComplete; - }); - it('opens lnode wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has two wizard pages', async () => { - expect(parent.wizardUI.dialogs.length).to.equal(2); - }); - }); - describe('move action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - let element2: ConductingEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`${Array.from( - doc?.querySelectorAll( - 'Bay[name="COUPLING_BAY"] > ConductingEquipment' - ) ?? [] - ).map( - condEq => - html`` - )} - >` - ) - ); - element = parent.querySelector( - 'conducting-equipment-editor:nth-child(1)' - ); - element2 = parent.querySelector( - 'conducting-equipment-editor:nth-child(2)' - ); - }); - it('moves ConductingEquipment within Bay', async () => { - expect( - doc.querySelector('ConductingEquipment')?.getAttribute('name') - ).to.equal('QA1'); - (( - element2?.shadowRoot?.querySelector('*[icon="forward"]') - )).click(); - await parent.updateComplete; - (element).click(); - await parent.updateComplete; - expect( - doc.querySelector('ConductingEquipment')?.getAttribute('name') - ).to.equal('QB1'); - }); - }); - describe('remove action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('conducting-equipment-editor'); - }); - it('removes ConductingEquipment on clicking delete button', async () => { - expect(doc.querySelector('ConductingEquipment[name="QA1"]')).to.exist; - (( - element?.shadowRoot?.querySelector('*[icon="delete"]') - )).click(); - await parent.updateComplete; - expect(doc.querySelector('ConductingEquipment[name="QA1"]')).to.not.exist; - }); - }); - - describe('open create wizard for element EqFunction', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('conducting-equipment-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="EqFunction"]') - )).click(); - await parent.requestUpdate(); - - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add EqFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment > EqFunction[name="myEqFuncQA1"]' - ) - ).to.exist; - - nameField.value = 'myEqFuncQA1'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'ConductingEquipment > EqFunction[name="myEqFuncQA1"]' - ).length - ).to.equal(1); - }); - - it('does add EqFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment > EqFunction[name="someNewFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment > EqFunction[name="someNewFunction"]' - ) - ).to.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ConductingEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('conducting-equipment-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding.test.ts b/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding.test.ts deleted file mode 100644 index 2e0fd5a6e6..0000000000 --- a/packages/plugins/test/integration/editors/substation/conducting-equipment-editor-wizarding.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../../src/editors/substation/conducting-equipment-editor.js'; -import { regexString, regExp } from '../../../foundation.js'; - -describe('conducting-equipment-editor wizarding integration', () => { - let doc: XMLDocument; - let parent: OscdWizards; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = await fixture( - html`` - ); - - (( - parent - ?.querySelector('conducting-equipment-editor') - ?.shadowRoot?.querySelector('*[icon="edit"]') - )).click(); - await parent.updateComplete; - }); - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - it('the first input element only displaying the type', () => { - expect(parent.wizardUI.inputs[0]).to.have.property('disabled', true); - }); - describe('the second input element', () => { - it('edits the attribute name', async () => { - expect(parent.wizardUI.inputs[1].label).to.equal('name'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tName, 1), async name => { - parent.wizardUI.inputs[1].value = name; - await parent.updateComplete; - expect(parent.wizardUI.inputs[0].checkValidity()).to.be.true; - }) - ); - }); - }); - describe('the third input element', () => { - it('edits the attribute desc', async () => { - expect(parent.wizardUI.inputs[2].label).to.equal('desc'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.desc), async desc => { - parent.wizardUI.inputs[2].value = desc; - await parent.updateComplete; - expect(parent.wizardUI.inputs[1].checkValidity()).to.be.true; - }) - ); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/eq-function-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/eq-function-wizarding-editing.test.ts deleted file mode 100644 index 68218bffdf..0000000000 --- a/packages/plugins/test/integration/editors/substation/eq-function-wizarding-editing.test.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/eq-function-editor.js'; -import { EqFunctionEditor } from '../../../../src/editors/substation/eq-function-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: EqFunctionEditor -) => Promise = ( - parent: MockWizardEditor, - element: EqFunctionEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('eq-function-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: EqFunctionEditor | null; - - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` EqFunction' - )} - >` - ) - ); - - element = parent.querySelector('eq-function-editor'); - }); - - describe('open create wizard for element EqSubFunction', () => { - let nameField: WizardTextField; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector( - 'mwc-list-item[value="EqSubFunction"]' - ) - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add EqSubFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]' - ) - ).to.exist; - - nameField.value = 'myEqSubFunc'; - primaryAction.click(); - - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]' - ).length - ).to.equal(1); - }); - - it('does add EqFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewEqSubFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]' - ) - ).to.exist; - }); - }); - - describe('open edit wizard', () => { - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="myEqFuncQB3"]' - )!; - - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.requestUpdate(); - - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update Function if name attribute is not unique', async () => { - expect( - doc.querySelectorAll( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="myEqFuncQB2"]' - ) - ).to.lengthOf(1); - - nameField.value = 'myEqFuncQB2'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="myEqFuncQB2"]' - ) - ).to.lengthOf(1); - }); - - it('does update Function if name attribute is unique', async () => { - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="someNewFunction"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="myEqFuncQB3"]' - ) - ).to.not.exist; - }); - }); - - describe('open create wizard for element LNode', () => { - let listItems: ListItemBase[]; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="LNode"]') - )).click(); - await parent.requestUpdate(); - - await parent.updateComplete; - - listItems = Array.from( - parent.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('add selected LNode instances to SubFcuntion parent', async () => { - listItems[3].selected = true; - listItems[5].selected = true; - - await primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] > EqFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] > EqFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="2"]' - ) - ).to.exist; - }); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached EqFunction element from the document', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]' - ) - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubFunc"]' - ) - ).to.not.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: EqFunctionEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` EqFunction' - )} - >` - ) - ); - - element = parent.querySelector('eq-function-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/eq-sub-function-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/eq-sub-function-editor-wizarding-editing.test.ts deleted file mode 100644 index b1037a380e..0000000000 --- a/packages/plugins/test/integration/editors/substation/eq-sub-function-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/eq-sub-function-editor.js'; -import { EqSubFunctionEditor } from '../../../../src/editors/substation/eq-sub-function-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: EqSubFunctionEditor -) => Promise = ( - parent: MockWizardEditor, - element: EqSubFunctionEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodeMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodeMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('eq-sub-function-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: EqSubFunctionEditor | null; - - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('eq-sub-function-editor'); - }); - - describe('open create wizard for element EqSubFunction', () => { - let nameField: WizardTextField; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector( - 'mwc-list-item[value="EqSubFunction"]' - ) - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add EqSubFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - ) - ).to.exist; - - nameField.value = 'myEqSubSubFunction'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - ).length - ).to.equal(1); - }); - - it('does add EqFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewEqSubFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewEqSubFunction"]' - ) - ).to.exist; - }); - }); - - describe('open edit wizard', () => { - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - )!; - - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update EqSubFunction if name attribute is not unique', async () => { - expect( - doc.querySelectorAll( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqFunc2"]' - ) - ).to.lengthOf(1); - - nameField.value = 'myEqFunc2'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqFunc2"]' - ) - ).to.lengthOf(1); - }); - - it('does update EqSubFunction if name attribute is unique', async () => { - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="someNewFunction"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - ) - ).to.not.exist; - }); - }); - - describe('open create wizard for element LNode', () => { - let listItems: ListItemBase[]; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="LNode"]') - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - listItems = Array.from( - parent.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('add selected LNode instances to SubFcuntion parent', async () => { - listItems[3].selected = true; - listItems[5].selected = true; - - await primaryAction.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="2"]' - ) - ).to.exist; - }); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached Function element from the document', async () => { - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - ) - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - ) - ).to.not.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: EqSubFunctionEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` EqFunction' - )} - >` - ) - ); - - element = parent.querySelector('eq-sub-function-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/function-editor.test.ts b/packages/plugins/test/integration/editors/substation/function-editor.test.ts deleted file mode 100644 index 499712f241..0000000000 --- a/packages/plugins/test/integration/editors/substation/function-editor.test.ts +++ /dev/null @@ -1,288 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/function-editor.js'; -import { FunctionEditor } from '../../../../src/editors/substation/function-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: FunctionEditor -) => Promise = ( - parent: MockWizardEditor, - element: FunctionEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const subFunctionMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='SubFunction']` - )!; - subFunctionMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('function-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: FunctionEditor | null; - - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('function-editor'); - }); - - describe('open create wizard for element SubFunction', () => { - let nameField: WizardTextField; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="SubFunction"]') - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add SubFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'Substation > Function > SubFunction[name="mySubFunc"]' - ) - ).to.exist; - - nameField.value = 'mySubFunc'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'Substation > Function > SubFunction[name="mySubFunc"]' - ).length - ).to.equal(1); - }); - - it('does add SubFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'Substation > Function > SubFunction[name="someNewFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'Substation > Function > SubFunction[name="someNewFunction"]' - ) - ).to.exist; - }); - }); - - describe('open edit wizard', () => { - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"]' - )!; - - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.requestUpdate(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update Function if name attribute is not unique', async () => { - expect( - doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] > Function[name="bay2Func"]' - ) - ).to.lengthOf(1); - - nameField.value = 'bay2Func'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] > Function[name="bay2Func"]' - ) - ).to.lengthOf(1); - }); - - it('does update Function if name attribute is unique', async () => { - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="someNewFunction"]' - ) - ).to.exist; - expect( - doc.querySelector('Bay[name="COUPLING_BAY"] > Function[name="bayName"]') - ).to.not.exist; - }); - }); - - describe('open create wizard for element LNode', () => { - let listItems: ListItemBase[]; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="LNode"]') - )).click(); - await parent.requestUpdate(); - - await parent.updateComplete; - - listItems = Array.from( - parent.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('add selected LNode instances to Function parent', async () => { - listItems[3].selected = true; - listItems[5].selected = true; - - await primaryAction.click(); - - expect( - doc.querySelector( - 'Function > LNode[iedName="None"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'Function > LNode[iedName="None"][lnClass="CSWI"][lnInst="2"]' - ) - ).to.exist; - }); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached Function element from the document', async () => { - expect( - doc.querySelector('Substation[name="AA1"] > Function[name="myFunc"]') - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector('Substation[name="AA1"] > Function[name="myFunc"]') - ).to.not.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: FunctionEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('function-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/general-equipment-editor-wizard-editing.test.ts b/packages/plugins/test/integration/editors/substation/general-equipment-editor-wizard-editing.test.ts deleted file mode 100644 index e13d46d655..0000000000 --- a/packages/plugins/test/integration/editors/substation/general-equipment-editor-wizard-editing.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/general-equipment-editor.js'; -import { GeneralEquipmentEditor } from '../../../../src/editors/substation/general-equipment-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: GeneralEquipmentEditor -) => Promise = ( - parent: MockWizardEditor, - element: GeneralEquipmentEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"][dialogaction="close"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('general-equipment-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: GeneralEquipmentEditor | null; - - describe('edit wizard', () => { - let nameField: WizardTextField; - let descField: WizardTextField; - let typeField: WizardTextField; - let secondaryAction: HTMLElement; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('general-equipment-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-fab[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - typeField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="type"]') - ); - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - it('changes name attribute on primary action', async () => { - parent.wizardUI.inputs[0].value = 'newName'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('GeneralEquipment')?.getAttribute('name') - ).to.equal('newName'); - }); - it('changes type attribute on primary action', async () => { - parent.wizardUI.inputs[2].value = 'newAXN'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('GeneralEquipment')?.getAttribute('type') - ).to.equal('newAXN'); - }); - it('changes desc attribute on primary action', async () => { - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('GeneralEquipment')?.getAttribute('desc') - ).to.equal('newDesc'); - }); - it('deletes desc attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - await primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('GeneralEquipment')?.getAttribute('desc')).to.be - .null; - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-fab[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached GeneralEquipment element from the document', async () => { - expect( - doc.querySelector( - 'Substation[name="AA1"] > GeneralEquipment[name="genSub"]' - ) - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector( - 'Substation[name="AA1"] > GeneralEquipment[name="genSub"]' - ) - ).to.not.exist; - }); - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: GeneralEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('general-equipment-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/guess-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/guess-wizarding-editing.test.ts deleted file mode 100644 index 25a37ce791..0000000000 --- a/packages/plugins/test/integration/editors/substation/guess-wizarding-editing.test.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { guessVoltageLevel } from '../../../../src/editors/substation/guess-wizard.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; -import { CheckListItem } from '@material/mwc-list/mwc-check-list-item.js'; - -describe('guess-wizard-integration', () => { - let element: OscdWizards; - let validSCL: XMLDocument; - beforeEach(async () => { - validSCL = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const substation = validSCL.querySelector('Substation')!; - substation.innerHTML = ''; - element = await fixture( - html`` - ); - - const wizard = guessVoltageLevel(validSCL, substation); - element.dispatchEvent(newWizardEvent(() => wizard)); - await element.requestUpdate(); - }); - - describe('renders one wizard page', () => { - it('asking which ctlModel the is used for switchgear', async () => { - expect(element.wizardUI.dialogs.length).to.equal(1); - expect( - element.wizardUI.dialog!.querySelectorAll( - '#ctlModelList > mwc-check-list-item' - ).length - ).to.equal(5); - }); - - it('the first one being status-only', async () => { - expect( - element.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(1)' - )?.innerHTML - ).to.equal('status-only'); - }); - - it('the second one being direct-with-normal-security', async () => { - expect( - element.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(2)' - )?.innerHTML - ).to.equal('direct-with-normal-security'); - }); - - it('the second one being direct-with-enhanced-security', async () => { - expect( - element.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(3)' - )?.innerHTML - ).to.equal('direct-with-enhanced-security'); - }); - - it('the second one being sbo-with-normal-security', async () => { - expect( - element.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(4)' - )?.innerHTML - ).to.equal('sbo-with-normal-security'); - }); - - it('the second one being sbo-with-enhanced-security', async () => { - expect( - element.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(5)' - )?.innerHTML - ).to.equal('sbo-with-enhanced-security'); - }); - }); -}); - -describe('guess-wizarding-editing-integration', () => { - let mockWizardEditor: MockWizardEditor; - let validSCL: XMLDocument; - - beforeEach(async () => { - validSCL = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const substation = validSCL.querySelector('Substation')!; - substation.innerHTML = ''; - mockWizardEditor = ( - await fixture(html``) - ); - - const wizard = guessVoltageLevel(validSCL, substation); - mockWizardEditor.dispatchEvent(newWizardEvent(wizard)); - await mockWizardEditor.wizardUI.dialog?.updateComplete; - - await mockWizardEditor.requestUpdate(); - await mockWizardEditor.updateComplete; - await mockWizardEditor.wizardUI.requestUpdate(); - - (( - mockWizardEditor.wizardUI.dialog!.querySelector( - '#ctlModelList > mwc-check-list-item:nth-child(5)' - ) - )).selected = true; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - await mockWizardEditor.requestUpdate(); - await mockWizardEditor.updateComplete; - - (( - mockWizardEditor.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - )).click(); - await mockWizardEditor.wizardUI.dialog?.requestUpdate(); - - await mockWizardEditor.requestUpdate(); - await mockWizardEditor.updateComplete; - }); - - it('creates only one voltage level with default name', () => { - expect( - validSCL.querySelectorAll(':root > Substation > VoltageLevel').length - ).to.equal(1); - expect( - validSCL - .querySelector(':root > Substation > VoltageLevel') - ?.getAttribute('name') - ).to.equal('E1'); - expect( - validSCL - .querySelector(':root > Substation > VoltageLevel') - ?.getAttribute('desc') - ).to.equal('guessed by OpenSCD'); - }); - - it('creates as many bays as ieds with lnType CSWI and ctlModel sbo-with-enhanced-security', async () => { - expect( - validSCL.querySelectorAll(':root > Substation > VoltageLevel > Bay') - .length - ).to.equal(1); - }); - it('creates correct number of conducting equipments', () => { - expect( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment' - ).length - ).to.equal(4); - }); - it('creates only unique conducting equipment names', () => { - const nameArray: string[] = Array.from( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment' - ) - ).map(item => item.getAttribute('name')!); - const nameSet = new Set(nameArray); - expect(nameArray.length).to.equal(nameSet.size); - }); - it('creates unique conducting equipment name, if no prefix is there', () => { - expect( - validSCL - .querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(1)' - ) - ?.getAttribute('name') - ).to.equal('QA1'); - expect( - validSCL - .querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(4)' - ) - ?.getAttribute('name') - ).to.equal('QB1'); - }); - it('uses prefix for conducting equipment name, if prefix is available', () => { - expect( - validSCL - .querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(2)' - ) - ?.getAttribute('name') - ).to.equal('CB2'); - expect( - validSCL - .querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(3)' - ) - ?.getAttribute('name') - ).to.equal('DC1'); - }); - it('automatically adds loginal nodes to the first conducting equipment', () => { - expect( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(1) > LNode' - ).length - ).to.equal(2); - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(1) > LNode[iedName="IED1"][ldInst="CircuitBreaker_CB1"][lnClass="XCBR"][lnInst="1"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(1) > LNode[iedName="IED1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - }); - it('automatically adds loginal nodes to the second conducting equipment', () => { - expect( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(2) > LNode' - ).length - ).to.equal(2); - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(2) > LNode[iedName="IED1"][ldInst="CircuitBreaker_CB1"][prefix="CB"][lnClass="XCBR"][lnInst="2"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(2) > LNode[iedName="IED1"][ldInst="CircuitBreaker_CB1"][prefix="CB"][lnClass="CSWI"][lnInst="2"]' - ) - ).to.exist; - }); - it('automatically adds loginal nodes to the third conducting equipment', () => { - expect( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(3) > LNode' - ).length - ).to.equal(3); - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(3) > LNode[iedName="IED1"][ldInst="Disconnectors"][prefix="DC"][lnClass="XSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(3) > LNode[iedName="IED1"][ldInst="Disconnectors"][prefix="DC"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(3) > LNode[iedName="IED1"][ldInst="Disconnectors"][prefix="DC"][lnClass="CILO"][lnInst="1"]' - ) - ).to.exist; - }); - it('automatically adds loginal nodes to the fourth conducting equipment', () => { - expect( - validSCL.querySelectorAll( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(4) > LNode' - ).length - ).to.equal(3); - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(4) > LNode[iedName="IED1"][ldInst="Disconnectors"][lnClass="XSWI"][lnInst="3"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(4) > LNode[iedName="IED1"][ldInst="Disconnectors"][lnClass="CSWI"][lnInst="3"]' - ) - ).to.exist; - expect( - validSCL.querySelector( - ':root > Substation > VoltageLevel > Bay > ConductingEquipment:nth-child(4) > LNode[iedName="IED1"][ldInst="Disconnectors"][lnClass="CILO"][lnInst="3"]' - ) - ).to.exist; - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/ied-editor-wizarding-integration.test.ts b/packages/plugins/test/integration/editors/substation/ied-editor-wizarding-integration.test.ts deleted file mode 100644 index 9c532db370..0000000000 --- a/packages/plugins/test/integration/editors/substation/ied-editor-wizarding-integration.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/ied-editor.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; -import { IedEditor } from '../../../../src/editors/substation/ied-editor.js'; - -describe('IED editor component wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let iededitor: IedEditor; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const ied = doc.querySelector('IED[name="IED2"]'); - - parent = ( - await fixture( - html`` - ) - ); - iededitor = parent.querySelector('ied-editor'); - await parent.updateComplete; - }); - - it('opens select wizard showing GSEControl of one IED', async () => { - (( - iededitor.shadowRoot?.querySelector('mwc-fab[class="selectgse"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect(parent.wizardUI.dialog).to.exist; - const gseControlList = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - await gseControlList.updateComplete; - - expect(gseControlList.items.length).to.equal( - doc.querySelectorAll('IED[name="IED2"] GSEControl').length - ); - }); - - it('opens select wizard showing ReportControl of one IED', async () => { - (( - iededitor.shadowRoot?.querySelector('mwc-fab[class="selectreport"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect(parent.wizardUI.dialog).to.exist; - const reportControlList = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - await reportControlList.updateComplete; - - expect(reportControlList.items.length).to.equal( - doc.querySelectorAll('IED[name="IED2"] ReportControl').length - ); - }); - - it('opens wizard showing References of one IED', async () => { - (( - iededitor.shadowRoot?.querySelector('mwc-fab[class="delete"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect(parent.wizardUI.dialog).to.exist; - const referencesList = - parent.wizardUI.dialog?.querySelectorAll('mwc-list-item'); - - expect(referencesList).to.be.not.undefined; - expect(referencesList!.length).to.equal(7); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/l-node-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/l-node-editor-wizarding-editing.test.ts deleted file mode 100644 index be33481062..0000000000 --- a/packages/plugins/test/integration/editors/substation/l-node-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/l-node-editor.js'; -import { LNodeEditor } from '../../../../src/editors/substation/l-node-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; - -describe('l-node-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: LNodeEditor | null; - - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = ( - await fixture( - html` LNode[lnClass="CSWI"]')} - >` - ) - ); - - element = parent.querySelector('l-node-editor'); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-fab[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached LNode element from the document', async () => { - expect(doc.querySelector('Substation > LNode[lnClass="CSWI"]')).to.exist; - - await deleteButton.click(); - - expect(doc.querySelector('Substation > LNode[lnClass="CSWI"]')).to.not - .exist; - }); - }); - - describe('has a edit icon button that', () => { - let prefixField: WizardTextField; - let lnInstField: WizardTextField; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'SubFunction[name="myBaySubFunc"] > LNode[lnClass="XSWI"]' - )!; - - (( - element?.shadowRoot?.querySelector('mwc-fab[icon="edit"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - prefixField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="prefix"]' - ) - ); - - lnInstField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="lnInst"]' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await parent.updateComplete; - }); - - it('changes prefix attribute on primary action', async () => { - prefixField.value = 'newPref'; - - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelector( - 'SubFunction[name="myBaySubFunc"] > LNode[lnClass="XSWI"]' - ) - ).to.have.attribute('prefix', 'newPref'); - }); - - it('changes lnInst attribute on primary action', async () => { - lnInstField.value = '31'; - - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelector( - 'SubFunction[name="myBaySubFunc"] > LNode[lnClass="XSWI"]' - ) - ).to.have.attribute('lnInst', '31'); - }); - }); - - describe('has a copy content icon button that', () => { - let contentCopyButton: HTMLElement; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'SubFunction[name="mySubFunc2"] > LNode[lnClass="XSWI"]' - )!; - await parent.updateComplete; - - contentCopyButton = ( - element?.shadowRoot?.querySelector('mwc-fab[icon="content_copy"]') - ); - await parent.updateComplete; - }); - - it('adds new LNode element', async () => { - contentCopyButton.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'SubFunction[name="mySubFunc2"] > LNode[lnClass="XSWI"]' - ) - ).to.have.lengthOf(3); - }); - - it('makes sure the lnInst is always unique', async () => { - contentCopyButton.click(); - contentCopyButton.click(); - contentCopyButton.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'SubFunction[name="mySubFunc2"] > LNode[lnClass="XSWI"]' - ) - ).to.have.lengthOf(5); - - const lnInsts = Array.from( - doc.querySelectorAll( - 'SubFunction[name="mySubFunc2"] > LNode[lnClass="XSWI"]' - ) - ).map(lNode => lNode.getAttribute('lnInst')!); - - const duplicates = lnInsts.filter( - (item, index) => lnInsts.indexOf(item) !== index - ); - - expect(duplicates).to.lengthOf(0); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/line-editor-wizard-editing.test.ts b/packages/plugins/test/integration/editors/substation/line-editor-wizard-editing.test.ts deleted file mode 100644 index a787523c61..0000000000 --- a/packages/plugins/test/integration/editors/substation/line-editor-wizard-editing.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/line-editor.js'; -import { LineEditor } from '../../../../src/editors/substation/line-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: LineEditor -) => Promise = ( - parent: MockWizardEditor, - element: LineEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"][dialogaction="close"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('line-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: LineEditor | null; - - describe('edit wizard', () => { - let nameField: WizardTextField; - - let primaryAction: HTMLElement; - let secondaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/Line.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('line-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - - it('changes desc attribute on primary action', async () => { - parent.wizardUI.inputs[1].value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('Line[name="Berlin"]')?.getAttribute('desc') - ).to.equal('newDesc'); - }); - - it('changes type attribute on primary action', async () => { - parent.wizardUI.inputs[2].value = 'newType'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('Line[name="Berlin"]')?.getAttribute('type') - ).to.equal('newType'); - }); - - it('changes nomFreq attribute on primary action', async () => { - parent.wizardUI.inputs[3].value = '50'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('Line[name="Berlin"]')?.getAttribute('nomFreq') - ).to.equal('50'); - }); - - it('changes numPhases attribute on primary action', async () => { - parent.wizardUI.inputs[4].value = '3'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('Line[name="Berlin"]')?.getAttribute('numPhases') - ).to.equal('3'); - }); - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the Line element from the document', async () => { - expect(doc.querySelector('Line[name="Berlin"]')).to.exist; - await deleteButton.click(); - expect(doc.querySelector('Line[name="Berlin"]')).to.not.exist; - }); - }); - }); - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: LineEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/Line.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('line-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/lnodewizard.test.ts b/packages/plugins/test/integration/editors/substation/lnodewizard.test.ts deleted file mode 100644 index ef4f034667..0000000000 --- a/packages/plugins/test/integration/editors/substation/lnodewizard.test.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { List } from '@material/mwc-list'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import { lNodeWizard } from '../../../../src/wizards/lnode.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; - -describe('lnodewizard', () => { - let element: MockWizardEditor; - let doc: Document; - beforeEach(async () => { - doc = await fetch('/test/testfiles/lnodewizard.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - beforeEach(async () => { - element = ( - await fixture(html``) - ); - const wizard = lNodeWizard(doc.querySelector('Bay')!); - element.dispatchEvent(newWizardEvent(() => wizard)); - await element.requestUpdate(); - }); - - it('renders three wizard pages each in a mwc-dialog', async () => { - expect( - element.wizardUI.shadowRoot?.querySelectorAll('mwc-dialog').length - ).to.equal(2); - }); - - describe('the first page', () => { - it('renders a list of available IEDs in a mwc-list with checked items', () => { - expect( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog') - ?.querySelectorAll('mwc-check-list-item').length - ).to.equal(doc.querySelectorAll('IED').length); - }); - - it('selects the IEDs that are connected', () => { - expect( - (( - (element.wizardUI.dialogs[0].querySelector('#iedList')).selected - )).length - ).to.equal(1); - }); - - describe('the second page', () => { - it('adds logical nodes of the selected IEDs', async () => { - expect( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelectorAll('mwc-check-list-item').length - ).to.equal( - doc.querySelectorAll('IED[name="IED2"] LN0, IED[name="IED2"] LN') - .length - ); - }); - - it('selects logical nodes connected to the substation element', async () => { - expect( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelectorAll('mwc-check-list-item[selected]').length - ).to.have.equal(3); - }); - - it('disables logical nodes connected to another substation', async () => { - expect( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelectorAll('mwc-check-list-item[disabled]').length - ).to.have.equal(1); - }); - }); - - describe('lNodeActions', () => { - it('removes unselected logical nodes', async () => { - expect( - doc.querySelector('Bay[name="COUPLING_BAY"]>LNode[lnClass="LLN0"]') - ).to.exist; - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('filtered-list') - )).items[0].click(); - await element.updateComplete; - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await element.updateComplete; - expect( - doc.querySelector('Bay[name="COUPLING_BAY"]>LNode[lnClass="LLN0"]') - ).to.not.exist; - }); - - it('creates selected logical nodes', async () => { - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"]>LNode[ldInst="CBSW"][lnClass="XCBR"][lnInst="1"]' - ) - ).to.not.exist; - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('filtered-list') - )).items[3].click(); - await element.updateComplete; - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await element.requestUpdate(); - - await element.updateComplete; - await element.wizards.updateComplete; - - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"]>LNode[ldInst="CBSW"][lnClass="XCBR"][lnInst="1"]' - ) - ).to.exist; - }); - it('only create and remove its own logical node references', async () => { - const allLNodesNumber = doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] LNode' - ).length; - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('filtered-list') - )).items[3].click(); - await element.updateComplete; - await element.wizards.updateComplete; - - (( - element.wizardUI.shadowRoot - ?.querySelector('mwc-dialog:nth-child(2)') - ?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await element.updateComplete; - expect( - doc.querySelectorAll('Bay[name="COUPLING_BAY"] LNode').length - ).to.equal(allLNodesNumber + 1); - }); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/powertransformer-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/powertransformer-editor-wizarding-editing.test.ts deleted file mode 100644 index d14cdbe67c..0000000000 --- a/packages/plugins/test/integration/editors/substation/powertransformer-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/powertransformer-editor.js'; -import { PowerTransformerEditor } from '../../../../src/editors/substation/powertransformer-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: PowerTransformerEditor -) => Promise = ( - parent: MockWizardEditor, - element: PowerTransformerEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('powertransformer-editor wizarding editing integration', () => { - describe('open create wizard for element EqFunction', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: PowerTransformerEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('powertransformer-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="EqFunction"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add EqFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'PowerTransformer[name="myPtr2"] > EqFunction[name="myEqFuncPtr2"]' - ) - ).to.exist; - - nameField.value = 'myEqFuncPtr2'; - primaryAction.click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect( - doc.querySelectorAll( - 'PowerTransformer[name="myPtr2"] > EqFunction[name="myEqFuncPtr2"]' - ).length - ).to.equal(1); - }); - - it('does add EqFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'PowerTransformer[name="myPtr2"] > EqFunction[name="someNewFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'PowerTransformer[name="myPtr2"] > EqFunction[name="someNewFunction"]' - ) - ).to.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: PowerTransformerEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('powertransformer-editor'); - - await parent.updateComplete; - await parent.wizardUI.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - - it('Should add SubEquipment', async () => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - - element?.shadowRoot - ?.querySelector(`mwc-list-item[value='SubEquipment']`)! - .click(); - - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const nameTextField: WizardTextField = - parent.wizardUI!.dialog!.querySelector( - 'wizard-textfield[label="name"]' - )!; - - const subEquipmentName = 'unique-name'; - - nameTextField.value = subEquipmentName; - - await parent.updateComplete; - - const primaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - `PowerTransformer[name="myPtr2"] > SubEquipment[name="${subEquipmentName}"]` - ).length - ).to.equal(1); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/process-editor-wizard-editing.test.ts b/packages/plugins/test/integration/editors/substation/process-editor-wizard-editing.test.ts deleted file mode 100644 index a3f6a61bf0..0000000000 --- a/packages/plugins/test/integration/editors/substation/process-editor-wizard-editing.test.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/process-editor.js'; -import { ProcessEditor } from '../../../../src/editors/substation/process-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: ProcessEditor -) => Promise = ( - parent: MockWizardEditor, - element: ProcessEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"][dialogaction="close"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('process-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ProcessEditor | null; - - describe('edit wizard', () => { - let nameField: WizardTextField; - let descField: WizardTextField; - let typeField: WizardTextField; - - let primaryAction: HTMLElement; - let secondaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/Process.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('process-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - typeField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="type"]') - ); - - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - - it('changes name attribute on primary action', async () => { - nameField.value = 'newName'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Process')?.getAttribute('name')).to.equal( - 'newName' - ); - }); - - it('changes desc attribute on primary action', async () => { - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - descField.value = 'newDesc'; - console.log(descField.value); - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector('Process[name="ProcessGenConduct"]') - ?.getAttribute('desc') - ).to.equal('newDesc'); - }); - - it('deletes desc attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - await primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector('Process[name="ProcessGenConduct"]') - ?.getAttribute('desc') - ).to.be.null; - }); - - it('changes type attribute on primary action', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); - typeField.nullSwitch!.click(); - await parent.updateComplete; - typeField.value = 'newType'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector('Process[name="ProcessGenConduct"]') - ?.getAttribute('type') - ).to.equal('newType'); - }); - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the Process element from the document', async () => { - expect(doc.querySelector('Process[name="ProcessGenConduct"]')).to.exist; - await deleteButton.click(); - expect(doc.querySelector('Process[name="ProcessGenConduct"]')).to.not - .exist; - }); - }); - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: ProcessEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/Process.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('process-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/sub-equipment-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/sub-equipment-wizarding-editing.test.ts deleted file mode 100644 index 03cbba5014..0000000000 --- a/packages/plugins/test/integration/editors/substation/sub-equipment-wizarding-editing.test.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/sub-equipment-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { SubEquipmentEditor } from '../../../../src/editors/substation/sub-equipment-editor.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: SubEquipmentEditor -) => Promise = ( - parent: MockWizardEditor, - element: SubEquipmentEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('sub-equipment-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('sub-equipment-editor'); - }); - - describe('open edit wizard', () => { - let nameField: WizardTextField; - let virtualField: WizardCheckbox; - let primaryAction: HTMLElement; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - virtualField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update SubEquipment if name attribute is not unique', async () => { - nameField.value = 'addEqi'; - primaryAction.click(); - await parent.updateComplete; - - expect(doc.querySelectorAll('SubEquipment[name="addEqi"]')).to.lengthOf( - 1 - ); - }); - - it('does update SubEquipment if name attribute is unique', async () => { - nameField.value = 'addEqi2'; - await parent.updateComplete; - primaryAction.click(); - - expect(doc.querySelector('SubEquipment[name="addEqi2"]')).to.exist; - expect(doc.querySelector('SubEquipment[name="subque"]')).to.not.exist; - }); - - it('does update SubEquipment when virtual is checked', async () => { - expect(virtualField.nullSwitch).to.exist; - - virtualField.nullSwitch?.click(); - - virtualField.maybeValue = 'true'; - - await parent.updateComplete; - primaryAction.click(); - - expect( - doc - .querySelector('SubEquipment[name="subque"]') - ?.hasAttribute('virtual') - ); - expect( - doc - .querySelector('SubEquipment[name="subque"]') - ?.getAttribute('virtual') - ).to.equal('true'); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached SubEquipment element from the document', async () => { - expect(doc.querySelector('SubEquipment[name="subque"]')).to.exist; - - await deleteButton.click(); - - expect(doc.querySelector('SubEquipment[name="subque"]')).to.not.exist; - }); - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubEquipmentEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('sub-equipment-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/sub-function-editor.test.ts b/packages/plugins/test/integration/editors/substation/sub-function-editor.test.ts deleted file mode 100644 index 13b4c4f2cd..0000000000 --- a/packages/plugins/test/integration/editors/substation/sub-function-editor.test.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/sub-function-editor.js'; -import { SubFunctionEditor } from '../../../../src/editors/substation/sub-function-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: SubFunctionEditor -) => Promise = ( - parent: MockWizardEditor, - element: SubFunctionEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const subFunctionMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='SubFunction']` - )!; - subFunctionMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('sub-function-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubFunctionEditor | null; - - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` SubFunction' - )} - >` - ) - ); - - element = parent.querySelector('sub-function-editor'); - }); - - describe('open create wizard for element SubFunction', () => { - let nameField: WizardTextField; - - beforeEach(async () => { - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="SubFunction"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add SubFunction if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'Function[name="voltLvName"] > SubFunction > SubFunction' - ) - ).to.exist; - - nameField.value = 'mySubSubFunction'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'Function[name="voltLvName"] > SubFunction > SubFunction' - ).length - ).to.equal(1); - }); - - it('does add SubFunction if name attribute is unique', async () => { - expect( - doc.querySelector( - 'Function[name="voltLvName"] > SubFunction > SubFunction[name="someNewSubFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewSubFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'Function[name="voltLvName"] > SubFunction > SubFunction[name="someNewSubFunction"]' - ) - ).to.exist; - }); - }); - - describe('open edit wizard', () => { - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - element!.element = doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"] > SubFunction[name="myBaySubFunc"]' - )!; - - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update SubFunction if name attribute is not unique', async () => { - expect( - doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] SubFunction[name="mySubFunc2"]' - ) - ).to.lengthOf(1); - - nameField.value = 'mySubFunc2'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'Bay[name="COUPLING_BAY"] SubFunction[name="mySubFunc2"]' - ) - ).to.lengthOf(1); - }); - - it('does update SubFunction if name attribute is unique', async () => { - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"] > SubFunction[name="someNewFunction"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"] > SubFunction[name="myBaySubFunc"]' - ) - ).to.not.exist; - }); - }); - - describe('open create wizard for element LNode', () => { - let listItems: ListItemBase[]; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` SubFunction' - )} - >` - ) - ); - - element = parent.querySelector('sub-function-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="LNode"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - listItems = Array.from( - parent.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('add selected LNode instances to SubFcuntion parent', async () => { - listItems[3].selected = true; - listItems[5].selected = true; - - await primaryAction.click(); - - expect( - doc.querySelector( - 'Function[name="voltLvName"] > SubFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="1"]' - ) - ).to.exist; - expect( - doc.querySelector( - 'Function[name="voltLvName"] > SubFunction > LNode[iedName="None"][lnClass="CSWI"][lnInst="2"]' - ) - ).to.exist; - }); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached SubFunction element from the document', async () => { - expect(doc.querySelector('Function[name="voltLvName"] > SubFunction')).to - .exist; - - await deleteButton.click(); - - expect(doc.querySelector('Function[name="voltLvName"] > SubFunction')).to - .not.exist; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubFunctionEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` SubFunction' - )} - >` - ) - ); - - element = parent.querySelector('sub-function-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/substation-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/substation-editor-wizarding-editing.test.ts deleted file mode 100644 index 0ea0f93ba3..0000000000 --- a/packages/plugins/test/integration/editors/substation/substation-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/substation-editor.js'; -import { SubstationEditor } from '../../../../src/editors/substation/substation-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: SubstationEditor -) => Promise = ( - parent: MockWizardEditor, - element: SubstationEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot?.querySelector('mwc-menu')!.click(); - const powerTransformerMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='PowerTransformer']` - )!; - powerTransformerMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); -describe('substation-editor wizarding editing integration', () => { - describe('edit wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - let nameField: WizardTextField; - let descField: WizardTextField; - let secondaryAction: HTMLElement; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('substation-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - it('changes name attribute on primary action', async () => { - nameField.value = 'newName'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Substation')?.getAttribute('name')).to.equal( - 'newName' - ); - }); - it('changes desc attribute on primary action', async () => { - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Substation')?.getAttribute('desc')).to.equal( - 'newDesc' - ); - }); - it('deletes desc attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Substation')?.getAttribute('desc')).to.be.null; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('substation-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); - - describe('open add voltage level wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('substation-editor'); - - (( - element?.shadowRoot?.querySelector( - 'mwc-list-item[value="VoltageLevel"]' - ) - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('opens voltage level wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has five wizard inputs', async () => { - expect(parent.wizardUI.inputs.length).to.equal(5); - }); - it('does not add voltage level if name attribute is not unique', async () => { - nameField.value = 'E1'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelectorAll('VoltageLevel[name="E1"]').length).to.equal( - 1 - ); - }); - it('does add voltage level if name attribute is unique', async () => { - nameField.value = 'J1'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel[name="J1"]')).to.exist; - }); - }); - describe('open lnode wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('substation-editor'); - - (( - element?.shadowRoot?.querySelector( - 'mwc-icon-button[icon="account_tree"]' - ) - )).click(); - await parent.updateComplete; - }); - it('opens lnode wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has two wizard pages', async () => { - expect(parent.wizardUI.dialogs.length).to.equal(2); - }); - }); - describe('remove action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('substation-editor'); - }); - it('removes Substation on clicking delete button', async () => { - expect(doc.querySelector('Substation')).to.exist; - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - )).click(); - await parent.updateComplete; - expect(doc.querySelector('Substation')).to.not.exist; - }); - }); - - describe('open create wizard for element Function', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('substation-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="Function"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add Function if name attribute is not unique', async () => { - expect(doc.querySelector('Substation > Function[name="myFunc"]')).to - .exist; - - nameField.value = 'myFunc'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll('Substation > Function[name="myFunc"]').length - ).to.equal(1); - }); - - it('does add Function if name attribute is unique', async () => { - expect(doc.querySelector('Substation > Function[name="someNewFunction"]')) - .to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - primaryAction.click(); - - expect(doc.querySelector('Substation > Function[name="someNewFunction"]')) - .to.exist; - }); - }); - - describe('open add general-equipment wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: SubstationEditor | null; - - let nameField: WizardTextField; - let typeField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('substation-editor'); - - (( - element?.shadowRoot?.querySelector( - 'mwc-list-item[value="GeneralEquipment"]' - ) - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - typeField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="type"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('opens general-equipment wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has four wizard inputs', async () => { - expect(parent.wizardUI.inputs.length).to.equal(4); - }); - it('does not add general-equipment if name andattribute is not unique', async () => { - nameField.value = 'genSub'; - typeField.value = 'AXN'; - await parent.updateComplete; - primaryAction.click(); - - expect( - doc.querySelectorAll('GeneralEquipment[name="genSub"]').length - ).to.equal(1); - }); - it('does add general-equipment if name attribute is unique', async () => { - expect(doc.querySelector('GeneralEquipment[name="newgenSub"]')).to.not - .exist; - nameField.value = 'newgenSub'; - typeField.value = 'AXN'; - await parent.updateComplete; - primaryAction.click(); - expect(doc.querySelector('GeneralEquipment[name = "newgenSub"]')).to - .exist; - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/substation-editor-wizarding.test.ts b/packages/plugins/test/integration/editors/substation/substation-editor-wizarding.test.ts deleted file mode 100644 index 179ef22be4..0000000000 --- a/packages/plugins/test/integration/editors/substation/substation-editor-wizarding.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../../src/editors/substation/substation-editor.js'; -import { regExp, regexString } from '../../../foundation.js'; - -describe('substation-editor wizarding integration', () => { - let doc: XMLDocument; - let parent: OscdWizards; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = await fixture( - html`` - ); - - (( - parent - ?.querySelector('substation-editor') - ?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - }); - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - describe('the first input element', () => { - it('edits the attribute name', async () => { - expect(parent.wizardUI.inputs[0].label).to.equal('name'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tName, 1), async name => { - parent.wizardUI.inputs[0].value = name; - await parent.updateComplete; - expect(parent.wizardUI.inputs[0].checkValidity()).to.be.true; - }) - ); - }); - }); - describe('the second input element', () => { - it('edits the attribute desc', async () => { - expect(parent.wizardUI.inputs[1].label).to.equal('desc'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.desc), async desc => { - parent.wizardUI.inputs[1].value = desc; - await parent.updateComplete; - expect(parent.wizardUI.inputs[1].checkValidity()).to.be.true; - }) - ); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/tapchanger-editor-wizard-editing.test.ts b/packages/plugins/test/integration/editors/substation/tapchanger-editor-wizard-editing.test.ts deleted file mode 100644 index 1818e46266..0000000000 --- a/packages/plugins/test/integration/editors/substation/tapchanger-editor-wizard-editing.test.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/tapchanger-editor.js'; -import { TapChangerEditor } from '../../../../src/editors/substation/tapchanger-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: TapChangerEditor -) => Promise = ( - parent: MockWizardEditor, - element: TapChangerEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"][dialogaction="close"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('tapchanger-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: TapChangerEditor | null; - - describe('edit wizard', () => { - let nameField: WizardTextField; - let descField: WizardTextField; - let primaryAction: HTMLElement; - let secondaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/TapChanger.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` TapChanger[name="tapChComplet"]' - )} - >` - ) - ); - element = parent.querySelector('tapchanger-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - - it('changes desc attribute on primary action', async () => { - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector( - 'TransformerWinding[name="withTapChanger1"] > TapChanger[name="tapChComplet"]' - ) - ?.getAttribute('desc') - ).to.equal('newDesc'); - }); - it('changes virtual attribute on primary action', async () => { - const virtualCheckbox = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'false'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector( - 'TransformerWinding[name="withTapChanger1"] > TapChanger[name="tapChComplet"]' - ) - ?.getAttribute('virtual') - ).to.equal('false'); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached TapChanger element from the document', async () => { - expect( - doc.querySelector( - 'TransformerWinding[name="withTapChanger1"] > TapChanger[name="tapChComplet"]' - ) - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector( - 'TransformerWinding[name="withTapChanger1"] > TapChanger[name="tapChComplet"]' - ) - ).to.not.exist; - }); - }); - }); - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: TapChangerEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/TapChanger.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` TapChanger[name="tapChComplet"]' - )} - >` - ) - ); - - element = parent.querySelector('tapchanger-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/transformer-winding-editor-wizard-editing.test.ts b/packages/plugins/test/integration/editors/substation/transformer-winding-editor-wizard-editing.test.ts deleted file mode 100644 index a45c7812a1..0000000000 --- a/packages/plugins/test/integration/editors/substation/transformer-winding-editor-wizard-editing.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import '../../../../src/editors/substation/transformer-winding-editor.js'; -import { TransformerWindingEditor } from '../../../../src/editors/substation/transformer-winding-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: TransformerWindingEditor -) => Promise = ( - parent: MockWizardEditor, - element: TransformerWindingEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const lnodMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='LNode']` - )!; - lnodMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"][dialogaction="close"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('transformer-winding-editor wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: TransformerWindingEditor | null; - - describe('edit wizard', () => { - let nameField: WizardTextField; - let descField: WizardTextField; - let primaryAction: HTMLElement; - let secondaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch( - 'test/testfiles/editors/substation/TransformerWinding.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` TransformerWinding[name="some"]' - )} - >` - ) - ); - element = parent.querySelector('transformer-winding-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - - it('changes desc attribute on primary action', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector( - 'PowerTransformer[name="pTransVolt"] > TransformerWinding[name="some"]' - ) - ?.getAttribute('desc') - ).to.equal('newDesc'); - }); - it('changes virtual attribute on primary action', async () => { - const virtualCheckbox = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc - .querySelector( - 'PowerTransformer[name="pTransVolt"] > TransformerWinding[name="some"]' - ) - ?.getAttribute('virtual') - ).to.equal('true'); - }); - - describe('has a delete icon button that', () => { - let deleteButton: HTMLElement; - - beforeEach(async () => { - deleteButton = ( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - ); - await parent.updateComplete; - }); - - it('removes the attached TransformerWinding element from the document', async () => { - expect( - doc.querySelector( - 'PowerTransformer[name="pTransVolt"] > TransformerWinding[name="some"]' - ) - ).to.exist; - - await deleteButton.click(); - - expect( - doc.querySelector( - 'PowerTransformer[name="pTransVolt"] > TransformerWinding[name="some"]' - ) - ).to.not.exist; - }); - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: TransformerWindingEditor | null; - - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/TransformerWinding.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html` TransformerWinding[name="some"]' - )} - >` - ) - ); - - element = parent.querySelector('transformer-winding-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding-editing.test.ts b/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding-editing.test.ts deleted file mode 100644 index ece59ac8ee..0000000000 --- a/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding-editing.test.ts +++ /dev/null @@ -1,577 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/voltage-level-editor.js'; -import { VoltageLevelEditor } from '../../../../src/editors/substation/voltage-level-editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base.js'; -import { MenuBase } from '@material/mwc-menu/mwc-menu-base.js'; - -const openAndCancelMenu: ( - parent: MockWizardEditor, - element: VoltageLevelEditor -) => Promise = ( - parent: MockWizardEditor, - element: VoltageLevelEditor -): Promise => - new Promise(async resolve => { - expect(parent.wizardUI.dialog).to.be.undefined; - - element?.shadowRoot - ?.querySelector("mwc-icon-button[icon='playlist_add']")! - .click(); - const powerTransformerMenuItem: ListItemBase = - element?.shadowRoot?.querySelector( - `mwc-list-item[value='PowerTransformer']` - )!; - - console.log(powerTransformerMenuItem); - powerTransformerMenuItem.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.exist; - - const secondaryAction: HTMLElement = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - expect(parent.wizardUI.dialog).to.be.undefined; - - return resolve(); - }); - -describe('voltage-level-editor wizarding editing integration', () => { - describe('edit wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - let nameField: WizardTextField; - let descField: WizardTextField; - let nomFreqField: WizardTextField; - let numPhasesField: WizardTextField; - let voltageField: WizardTextField; - let secondaryAction: HTMLElement; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('voltage-level-editor'); - await (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - nomFreqField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="nomFreq"]' - ) - ); - numPhasesField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="numPhases"]' - ) - ); - voltageField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="Voltage"]' - ) - ); - secondaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('closes on secondary action', async () => { - secondaryAction.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialog).to.not.exist; - }); - it('changes name attribute on primary action', async () => { - nameField.value = 'newName'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('name')).to.equal( - 'newName' - ); - }); - it('changes desc attribute on primary action', async () => { - descField.value = 'newDesc'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('desc')).to.equal( - 'newDesc' - ); - }); - it('deletes desc attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('desc')).to.be - .null; - }); - it('changes nomFreq attribute on primary action', async () => { - nomFreqField.value = '30'; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('VoltageLevel')?.getAttribute('nomFreq') - ).to.equal('30'); - }); - it('deletes nomFreq attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - nomFreqField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('nomFreq')).to.be - .null; - }); - it('changes numPhases attribute on primary action', async () => { - numPhasesField.value = '3'; - await parent.updateComplete; - primaryAction.click(); - expect( - doc.querySelector('VoltageLevel')?.getAttribute('numPhases') - ).to.equal('3'); - }); - it('deletes numPhases attribute if wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - numPhasesField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('numPhases')).to.be - .null; - }); - it('changes Voltage value on primary action', async () => { - voltageField.value = '20.0'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Voltage')?.innerHTML).to.equal('20.0'); - }); - it('changes Voltage multiplier on primary action', async () => { - voltageField.multiplier = 'M'; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('Voltage')?.getAttribute('multiplier')).to.equal( - 'M' - ); - expect(doc.querySelector('Voltage')?.getAttribute('unit')).to.equal('V'); - }); - it('deletes voltage element if voltage wizard-textfield is deactivated', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - voltageField.nullSwitch!.click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.querySelector('Voltage')).to.be - .null; - }); - }); - - describe('Open add wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('voltage-level-editor'); - - await parent.updateComplete; - }); - - it('Should open the same wizard for the second time', async () => { - await openAndCancelMenu(parent, element!); - await openAndCancelMenu(parent, element!); - }); - }); - - describe('open add bay wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('voltage-level-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="Bay"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('does add bay if name attribute is unique', async () => { - nameField.value = 'SecondBay'; - await new Promise(resolve => setTimeout(resolve, 100)); // update takes some time - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector('VoltageLevel[name="E1"] > Bay[name="SecondBay"]') - ).to.exist; - }); - }); - describe('open lnode wizard', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('voltage-level-editor'); - - (( - element?.shadowRoot?.querySelector( - 'mwc-icon-button[icon="account_tree"]' - ) - )).click(); - await parent.updateComplete; - }); - it('opens lnode wizard ', async () => { - expect(parent.wizardUI).to.exist; - }); - it('has two wizard pages', async () => { - expect(parent.wizardUI.dialogs.length).to.equal(2); - }); - }); - describe('move action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - let element2: VoltageLevelEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`${Array.from(doc?.querySelectorAll('VoltageLevel') ?? []).map( - vLevel => - html`` - )} - >` - ) - ); - element = parent.querySelector('voltage-level-editor:nth-child(1)'); - element2 = parent.querySelector('voltage-level-editor:nth-child(2)'); - }); - it('moves VoltageLevel within Substation', async () => { - expect(doc.querySelector('VoltageLevel')?.getAttribute('name')).to.equal( - 'E1' - ); - (( - element2?.shadowRoot?.querySelector('mwc-icon-button[icon="forward"]') - )).click(); - await parent.updateComplete; - (element).click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel')?.getAttribute('name')).to.equal( - 'J1' - ); - }); - }); - describe('remove action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('voltage-level-editor'); - }); - it('removes VoltageLevel on clicking delete button', async () => { - expect(doc.querySelector('VoltageLevel[name="E1"]')).to.exist; - (( - element?.shadowRoot?.querySelector('mwc-icon-button[icon="delete"]') - )).click(); - await parent.updateComplete; - expect(doc.querySelector('VoltageLevel[name="E1"]')).to.not.exist; - }); - }); - describe('clone action', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - let copyContentButton: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/clone/noUnusedLNode.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - element = parent.querySelector('voltage-level-editor'); - await parent.updateComplete; - - copyContentButton = ( - element?.shadowRoot?.querySelector( - 'mwc-icon-button[icon="content_copy"]' - ) - ); - }); - - it('duplicates VoltageLevel on clicking duplicate button', async () => { - copyContentButton.click(); - await parent.updateComplete; - - expect(doc.querySelector('VoltageLevel[name="E2"]')).to.exist; - }); - - it('removes all LNode elements in the copy', async () => { - expect( - doc.querySelector('VoltageLevel[name="E1"]')?.querySelector('LNode') - ).to.exist; - - copyContentButton.click(); - await parent.updateComplete; - - expect( - doc.querySelector('VoltageLevel[name="E2"]')?.querySelector('LNode') - ).to.not.exist; - }); - - it('removes all Terminal elements except the grounding in the copy', async () => { - expect( - doc - .querySelector('VoltageLevel[name="E1"]') - ?.querySelector('Terminal:not([cNodeName="grounded"])') - ).to.exist; - - copyContentButton.click(); - await parent.updateComplete; - - expect( - doc - .querySelector('VoltageLevel[name="E2"]') - ?.querySelector('Terminal:not([cNodeName="grounded"])') - ).to.not.exist; - }); - - it('removes all ConnectivityNode elements in the copy', async () => { - expect( - doc - .querySelector('VoltageLevel[name="E1"]') - ?.querySelector('ConnectivityNode') - ).to.exist; - - copyContentButton.click(); - await parent.updateComplete; - - expect( - doc - .querySelector('VoltageLevel[name="E2"]') - ?.querySelector('ConnectivityNode') - ).to.not.exist; - }); - - it('keeps all Bay elements in the copy', async () => { - copyContentButton.click(); - await parent.updateComplete; - expect( - doc.querySelector('VoltageLevel[name="E1"]')?.querySelectorAll('Bay') - .length - ).to.equal( - doc.querySelector('VoltageLevel[name="E2"]')?.querySelectorAll('Bay') - .length - ); - }); - - it('keeps all ConductingEquipment elements in the copy', async () => { - copyContentButton.click(); - await parent.updateComplete; - expect( - doc - .querySelector('VoltageLevel[name="E1"]') - ?.querySelectorAll('ConductingEquipment').length - ).to.equal( - doc - .querySelector('VoltageLevel[name="E2"]') - ?.querySelectorAll('ConductingEquipment').length - ); - }); - }); - - describe('open create wizard for element Function', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let element: VoltageLevelEditor | null; - - let nameField: WizardTextField; - let primaryAction: HTMLElement; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = ( - await fixture( - html`` - ) - ); - - element = parent.querySelector('voltage-level-editor'); - - (( - element?.shadowRoot?.querySelector('mwc-list-item[value="Function"]') - )).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not add Function if name attribute is not unique', async () => { - expect( - doc.querySelector( - 'VoltageLevel[name="E1"] > Function[name="voltLvName"]' - ) - ).to.exist; - - nameField.value = 'voltLvName'; - primaryAction.click(); - await parent.updateComplete; - - expect( - doc.querySelectorAll( - 'VoltageLevel[name="E1"] > Function[name="voltLvName"]' - ).length - ).to.equal(1); - }); - - it('does add Function if name attribute is unique', async () => { - expect( - doc.querySelector( - 'VoltageLevel[name="E1"] > Function[name="someNewFunction"]' - ) - ).to.not.exist; - - nameField.value = 'someNewFunction'; - await parent.updateComplete; - - primaryAction.click(); - - expect( - doc.querySelector( - 'VoltageLevel[name="E1"] > Function[name="someNewFunction"]' - ) - ).to.exist; - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding.test.ts b/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding.test.ts deleted file mode 100644 index 7596cf88d4..0000000000 --- a/packages/plugins/test/integration/editors/substation/voltage-level-editor-wizarding.test.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../../src/editors/substation/voltage-level-editor.js'; -import { regexString, regExp, inverseRegExp } from '../../../foundation.js'; -import { patterns } from '@openscd/open-scd/src/foundation.js'; - -describe('voltage-level-editor wizarding integration', () => { - let doc: XMLDocument; - let parent: OscdWizards; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = await fixture( - html`` - ); - - (( - parent - ?.querySelector('voltage-level-editor') - ?.shadowRoot?.querySelector('mwc-icon-button[icon="edit"]') - )).click(); - await parent.updateComplete; - }); - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot({ - ignoreAttributes: [ - { tags: ['wizard-textfield'], attributes: ['pattern'] }, - ], - }); - }); - //work around, because the escapes get removed in snapshot - it('should have correct pattern', async () => { - expect( - parent.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]') - .length - ).to.equal(2); - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')![0] - .getAttribute('pattern') - ).to.equal(patterns.unsigned); - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')![1] - .getAttribute('pattern') - ).to.equal(patterns.decimal); - }); - describe('the first input element', () => { - it('edits the attribute name', async () => { - expect(parent.wizardUI.inputs[0].label).to.equal('name'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tName, 1), async name => { - parent.wizardUI.inputs[0].value = name; - await parent.updateComplete; - expect(parent.wizardUI.inputs[0].checkValidity()).to.be.true; - }) - ); - }); - }); - describe('the second input element', () => { - it('edits the attribute desc', async () => { - expect(parent.wizardUI.inputs[1].label).to.equal('desc'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.desc), async desc => { - parent.wizardUI.inputs[1].value = desc; - await parent.updateComplete; - expect(parent.wizardUI.inputs[1].checkValidity()).to.be.true; - }) - ); - }); - }); - describe('the third input element', () => { - it('edits the attribute nomFreq', async () => { - expect(parent.wizardUI.inputs[2].label).to.equal('nomFreq'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.unsigned, 1), async nomFreq => { - parent.wizardUI.inputs[2].value = nomFreq; - await parent.updateComplete; - expect(parent.wizardUI.inputs[2].checkValidity()).to.be.true; - }) - ); - }); - it('requires a nonnegative value', async () => { - parent.wizardUI.inputs[2].value = ''; - await parent.updateComplete; - expect(parent.wizardUI.inputs[2].checkValidity()).to.be.false; - parent.wizardUI.inputs[2].value = '-50.'; - await parent.updateComplete; - expect(parent.wizardUI.inputs[2].checkValidity()).to.be.false; - parent.wizardUI.inputs[2].value = '+50.'; - await parent.updateComplete; - expect(parent.wizardUI.inputs[2].checkValidity()).to.be.true; - }); - it('rejects action for invalid inputs', async () => { - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.unsigned, 1), - async nomFreq => { - parent.wizardUI.inputs[2].value = nomFreq; - await parent.updateComplete; - expect(parent.wizardUI.inputs[2].checkValidity()).to.be.false; - } - ) - ); - }); - }); - describe('the fourth input element', () => { - it('edits the attribute ', async () => { - expect(parent.wizardUI.inputs[3].label).to.equal('numPhases'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(fc.integer(1, 255), async numPhases => { - parent.wizardUI.inputs[3].value = String(numPhases); - await parent.updateComplete; - expect(parent.wizardUI.inputs[3].checkValidity()).to.be.true; - }) - ); - }); - it('is of the type unsingedByte', async () => { - parent.wizardUI.inputs[3].value = '0'; - await parent.updateComplete; - expect(parent.wizardUI.inputs[3].checkValidity()).to.be.false; - parent.wizardUI.inputs[3].value = '256'; - await parent.updateComplete; - expect(parent.wizardUI.inputs[3].checkValidity()).to.be.false; - parent.wizardUI.inputs[3].value = '-65'; - await parent.updateComplete; - expect(parent.wizardUI.inputs[3].checkValidity()).to.be.false; - }); - it('rejects edition for invalid inputs', async () => { - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.integer, 1), - async nomFreq => { - parent.wizardUI.inputs[3].value = nomFreq; - await parent.updateComplete; - expect(parent.wizardUI.inputs[3].checkValidity()).to.be.false; - } - ) - ); - }); - }); - describe('the fifth input element', () => { - it('edits the attribute ', async () => { - expect(parent.wizardUI.inputs[4].label).to.equal('Voltage'); - }); - it('edits only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal), async nomFreq => { - parent.wizardUI.inputs[4].value = nomFreq; - await parent.updateComplete; - expect(parent.wizardUI.inputs[4].checkValidity()).to.be.true; - }) - ); - }); - it('rejects edition for invalid inputs', async () => { - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.decimal, 1), - async voltage => { - parent.wizardUI.inputs[4].value = voltage; - await parent.updateComplete; - expect(parent.wizardUI.inputs[4].checkValidity()).to.be.false; - } - ) - ); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/substation/zeroline-pane.test.ts b/packages/plugins/test/integration/editors/substation/zeroline-pane.test.ts deleted file mode 100644 index 029047448f..0000000000 --- a/packages/plugins/test/integration/editors/substation/zeroline-pane.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../../src/editors/substation/zeroline-pane.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; -import { ZerolinePane } from '../../../../src/editors/substation/zeroline-pane.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { IconButton } from '@material/mwc-icon-button'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -describe('zeroline-pane wizarding editing integration', () => { - let doc: XMLDocument; - let parent: MockWizardEditor; - let zeroline: ZerolinePane; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/comm-map.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = ( - await fixture( - html`` - ) - ); - zeroline = parent.querySelector('zeroline-pane'); - await parent.updateComplete; - }); - - it('opens selectGseControlWizard for the complete SCL file', async () => { - zeroline.gsecontrol.click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - expect(parent.wizardUI.dialog).to.exist; - const gseControlList = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - await gseControlList.updateComplete; - expect(gseControlList.items.length).to.equal( - doc.querySelectorAll('GSEControl').length - ); - }); - - it('opens selectSampledValueControlWizard for the complete SCL file', async () => { - zeroline.smvcontrol.click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect(parent.wizardUI.dialog).to.exist; - const smvControlList = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - await smvControlList.updateComplete; - expect(smvControlList.items.length).to.equal( - doc.querySelectorAll('SampledValueControl').length - ); - }); - - it('opens select wizard for SCL element ReportControl for the complete project', async () => { - zeroline.reportcontrol.click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect(parent.wizardUI.dialog).to.exist; - const reportControlList = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - await reportControlList.updateComplete; - expect(reportControlList.items.length).to.equal( - doc.querySelectorAll('ReportControl').length - ); - }); - - it('add Substation element with add button', async () => { - expect(doc.querySelector('Substation[name="newSubstation"]')).to.not.exist; - zeroline.addButton.click(); - (zeroline.addMenu.querySelector('[value=Substation]')).click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - const primaryAction = ( - parent.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - ); - await primaryAction.updateComplete; - const nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - nameField.value = 'newSubstation'; - await nameField.updateComplete; - primaryAction.click(); - - expect(doc.querySelector('Substation[name="newSubstation"]')).to.exist; - }); -}); diff --git a/packages/plugins/test/integration/editors/templates/Templates.test.ts b/packages/plugins/test/integration/editors/templates/Templates.test.ts deleted file mode 100644 index e453aa88f5..0000000000 --- a/packages/plugins/test/integration/editors/templates/Templates.test.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { html, fixture, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-open-scd.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -import TemplatesPlugin from '../../../../src/editors/Templates.js'; - -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; - -describe('Templates Plugin', () => { - customElements.define('templates-plugin', TemplatesPlugin); - - let element: TemplatesPlugin; - let parent: MockOpenSCD; - - beforeEach(async () => { - parent = await fixture( - html`` - ); - - element = parent.getActivePlugin(); - }); - - describe('without a doc loaded', () => { - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with a doc loaded', () => { - let doc: XMLDocument; - beforeEach(async () => { - doc = await fetch('/test/testfiles/templates/datypes.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.doc = doc; - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - - describe('having a LNodeType element list that', () => { - beforeEach(async () => { - parent.workflow.length = 0; - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[0] - .querySelector('mwc-list-item') - )).click(); - - await parent.requestUpdate(); - }); - - it('opens a LNodeType edit wizard on list element click', () => - expect( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="lnClass"]' - ) - ).to.exist); - - it('allows to reopen the LNodeType edit wizard for the same element', async () => { - parent.dispatchEvent(newWizardEvent()); - - await parent.requestUpdate(); - - (( - element?.shadowRoot?.querySelector( - 'filtered-list:nth-of-type(1) > mwc-list-item' - ) - )).click(); - await parent.requestUpdate(); - - expect( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="lnClass"]' - ) - ).to.exist; - }); - }); - - describe('having a DOType element list that', () => { - beforeEach(async () => { - parent.workflow.length = 0; - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[1] - .querySelector('mwc-list-item') - )).click(); - - await parent.requestUpdate(); - }); - - it('opens a DOType edit wizard on list element click', () => - expect( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="CDC"]') - ).to.exist); - - it('allows to reopen the DOType edit wizard for the same element', async () => { - parent.dispatchEvent(newWizardEvent()); - - await parent.requestUpdate(); - - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[1] - .querySelector('mwc-list-item') - )).click(); - await parent.requestUpdate(); - - expect( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="CDC"]') - ).to.exist; - }); - }); - - describe('having a DAType element list that', () => { - beforeEach(async () => { - parent.workflow.length = 0; - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[2] - .querySelector('mwc-list-item') - )).click(); - - await parent.requestUpdate(); - }); - - it('opens a DAType edit wizard on list element click', () => - expect(parent.wizardUI.dialog).to.exist); - - it('allows to reopen the DAType edit wizard for the same element', async () => { - parent.dispatchEvent(newWizardEvent()); - - await parent.requestUpdate(); - - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[3] - .querySelector('mwc-list-item') - )).click(); - await parent.requestUpdate(); - - expect(parent.wizardUI.dialog).to.exist; - }); - }); - - describe('having a EnumType element list that', () => { - beforeEach(async () => { - parent.workflow.length = 0; - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[3] - .querySelector('mwc-list-item') - )).click(); - - await parent.requestUpdate(); - }); - - it('opens a EnumType edit wizard on list element click', () => - expect(parent.wizardUI.dialog).to.exist); - - it('allows to reopen the EnumType edit wizard for the same element', async () => { - parent.dispatchEvent(newWizardEvent()); - - await parent.requestUpdate(); - - (( - element?.shadowRoot - ?.querySelectorAll('filtered-list')[3] - .querySelector('mwc-list-item') - )).click(); - await parent.requestUpdate(); - - expect(parent.wizardUI.dialog).to.exist; - }); - }); - }); - - describe('with a doc loaded missing a datatypetemplates section', () => { - let doc: XMLDocument; - let parent: MockOpenSCD; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/templates/missingdatatypes.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = await fixture( - html`` - ); - element = parent.getActivePlugin(); - await element.updateComplete; - }); - - it('has a mwc-fab', () => { - expect(element.shadowRoot?.querySelector('mwc-fab')).to.exist; - }); - - it('adds a DataTypeTemplates on floating action button click', async () => { - expect(doc.querySelector('DataTypeTemplates')).to.not.exist; - (( - parent - ?.querySelector('templates-plugin') - ?.shadowRoot?.querySelector('mwc-fab') - )).click(); - await parent.updateComplete; - expect( - parent! - .querySelector('templates-plugin')! - .doc!.querySelector('DataTypeTemplates') - ).to.exist; - }); - }); - - describe('with a doc loaded having a datatypetemplates section', () => { - let doc: XMLDocument; - let parent: MockOpenSCD; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/templates/datypes.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - parent = await fixture( - html`` - ); - element = parent.getActivePlugin(); - await element.updateComplete; - }); - - it('opens an add enumtype wizard', async () => { - expect(parent.wizardUI.dialogs.length).to.equal(0); - (( - parent - ?.querySelector('templates-plugin') - ?.shadowRoot?.querySelectorAll( - 'mwc-icon-button[icon="playlist_add"]' - )[2] - )).click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialogs.length).to.equal(1); - }); - - it('adding an EnumType with the enumtype wizard', async () => { - expect(doc.querySelectorAll('EnumType').length).to.equal(4); - (( - parent - ?.querySelector('templates-plugin') - ?.shadowRoot?.querySelector( - 'section:last-child mwc-icon-button[icon="playlist_add"]' - ) - )).click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - parent.wizardUI.inputs[1].value = 'myID'; - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - )).click(); - await parent.updateComplete; - expect(doc.querySelectorAll('EnumType').length).to.equal(5); - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/templates/__snapshots__/Templates.test.snap.js b/packages/plugins/test/integration/editors/templates/__snapshots__/Templates.test.snap.js deleted file mode 100644 index 5d0dc734b7..0000000000 --- a/packages/plugins/test/integration/editors/templates/__snapshots__/Templates.test.snap.js +++ /dev/null @@ -1,580 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Templates Plugin without a doc loaded looks like the latest snapshot"] = -`

    - - templates.missing - - - -

    -`; -/* end snapshot Templates Plugin without a doc loaded looks like the latest snapshot */ - -snapshots["Templates Plugin with a doc loaded looks like the latest snapshot"] = -`
    -
    -

    - Logical Node Type - -

    - - - - Dummy.LLN0 - - - LLN0 - - - 4 - - - - - Dummy.LPHD1 - - - LPHD - - - 4 - - - - - Dummy.XCBR1 - - - XCBR - - - 7 - - - - - Dummy.CSWI - - - CSWI - - - 5 - - - - - Dummy.CILO - - - CILO - - - 4 - - - - - Dummy.CSWIwithoutCtlModel - - - CSWI - - - 5 - - - - - Dummy.XSWI1 - - - XSWI - - - 7 - - - - - Dummy.GGIO1 - - - GGIO - - - 4 - - - -
    -
    -

    - Data Object Type - -

    - - - - Dummy.LLN0.Mod - - - ENC - - - 14 - - - - - Dummy.LLN0.Beh - - - ENS - - - 3 - - - - - Dummy.LLN0.Health - - - ENS - - - 3 - - - - - Dummy.LLN0.NamPlt - - - LPL - - - 5 - - - - - Dummy.LPHD1.PhyNam - - - DPL - - - 5 - - - - - Dummy.LPHD1.Sim - - - SPC - - - 15 - - - - - Dummy.XCBR1.Pos - - - DPC - - - 5 - - - - - Dummy.CSWI.Pos1 - - - DPC - - - 5 - - - - - Dummy.CSWI.Pos2 - - - DPC - - - 5 - - - - - Dummy.XCBR1.OpCnt - - - INS - - - 3 - - - - - Dummy.XCBR1.NamPlt - - - LPL - - - 3 - - - - - Dummy.XCBR1.BlkOpn - - - SPC - - - 5 - - - - - Dummy.SPS - - - SPS - - - 3 - - - -
    -
    -

    - Data Attribute Type - -

    - - - - Dummy_origin - - - 2 - - - - - Dummy.LLN0.Mod.SBOw - - - 6 - - - - - Dummy.LLN0.Mod.Cancel - - - 5 - - - - - Dummy.LPHD1.Sim.SBOw - - - 6 - - - - - Dummy.LPHD1.Sim.Cancel - - - 5 - - - -
    -
    -

    - Enum Type - -

    - - - - Dummy_ctlModel - - - 5 - - - - - Dummy_Beh - - - 5 - - - - - Dummy_Health - - - 3 - - - - - Dummy_orCategory - - - 9 - - - -
    -
    -`; -/* end snapshot Templates Plugin with a doc loaded looks like the latest snapshot */ - diff --git a/packages/plugins/test/integration/editors/templates/__snapshots__/datype-wizarding.test.snap.js b/packages/plugins/test/integration/editors/templates/__snapshots__/datype-wizarding.test.snap.js deleted file mode 100644 index 80f5d8d85c..0000000000 --- a/packages/plugins/test/integration/editors/templates/__snapshots__/datype-wizarding.test.snap.js +++ /dev/null @@ -1,781 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["DAType wizards defines a createDATypeWizard looks like the latest snapshot"] = -` -
    - - - - AnalogueValue_FLOAT32 - - - 1 - - - - - AnalogueValue_INT32 - - - 1 - - - - - Cancel_SPC - - - 5 - - - - - Cancel_Dbpos - - - 5 - - - - - Cancel_FLOAT32 - - - 5 - - - - - Cancel_StepControlKind - - - 5 - - - - - Cancel_BehaviourModeKind - - - 5 - - - - - Cancel_INT8 - - - 5 - - - - - CalendarTime - - - 8 - - - - - Cell2D - - - 4 - - - - - Cell1D - - - 2 - - - - - OperSBOw_SPC - - - 6 - - - - - OperSBOw_Dbpos - - - 6 - - - - - OperSBOw_FLOAT32 - - - 6 - - - - - OperSBOw_StepControlKind - - - 6 - - - - - OperSBOw_BehaviourModeKind - - - 6 - - - - - OperSBOw_INT8 - - - 6 - - - - - Originator - - - 2 - - - - - Point3D - - - 3 - - - - - Point2D - - - 2 - - - - - PulseConfig - - - 4 - - - - - RangeConfig - - - 7 - - - - - ScaledValueConfig_AmpSv - - - 2 - - - - - ScaledValueConfig_VolSv - - - 2 - - - - - Unit_A - - - 1 - - - - - Unit_V - - - 1 - - - - - Unit_Hz - - - 1 - - - - - ValWithTrans_wo_transInd - - - 1 - - - - - Vector_I_w_Ang - - - 2 - - - - - Vector_F_w_Ang - - - 2 - - - - - Vector_I_wo_Ang - - - 1 - - - - - Vector_F_wo_Ang - - - 1 - - - - - ScaledValueConfig - - - 2 - - - - - Unit - - - 2 - - - - - ValWithTrans - - - 2 - - - - - - - -
    - - - - -
    -`; -/* end snapshot DAType wizards defines a createDATypeWizard looks like the latest snapshot */ - -snapshots["DAType wizards defines a dATypeWizard looks like the latest snapshot"] = -` - -
    - - - - - - - - ctlVal - - - #Dummy_Beh - - - - - origin - - - #Dummy_origin - - - - - ctlNum - - - INT8U - - - - - T - - - Timestamp - - - - - Test - - - BOOLEAN - - - - - Check - - - Check - - - -
    - - - - -
    -`; -/* end snapshot DAType wizards defines a dATypeWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/integration/editors/templates/__snapshots__/dotype-wizarding.test.snap.js b/packages/plugins/test/integration/editors/templates/__snapshots__/dotype-wizarding.test.snap.js deleted file mode 100644 index 5519fd1c07..0000000000 --- a/packages/plugins/test/integration/editors/templates/__snapshots__/dotype-wizarding.test.snap.js +++ /dev/null @@ -1,1422 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["DOType wizards defines a createDOTypeWizard looks like the latest snapshot"] = -` -
    - - - - ACD_general - - - 4 - - - - - ACD_threephase - - - 10 - - - - - ACT_general_control - - - 4 - - - - - ACT_threephase_control - - - 7 - - - - - ACT_general - - - 3 - - - - - APC_VolSpt_ATCC - - - 8 - - - - - ASG_ATrg_TCTR - - - 5 - - - - - ASG_HzRtg_TCTR - - - 5 - - - - - ASG_VRtg_TVTR - - - 5 - - - - - BAC_BndCtrChg_ATCC - - - 9 - - - - - BSC_TapChg_ATCC - - - 8 - - - - - BSC_TapChg_YLTC - - - 5 - - - - - CMV_db_i_MagAndAng - - - 13 - - - - - DEL - - - 3 - - - - - DEL_wRef - - - 4 - - - - - DPL - - - 8 - - - - - DPC_statusonly - - - 4 - - - - - DPC - - - 11 - - - - - DPSsimple - - - 4 - - - - - ENS_Beh - - - 3 - - - - - ENC_Mod - - - 10 - - - - - ENC_Mod_statusonly - - - 5 - - - - - ENS_Health - - - 3 - - - - - ENS_SwTyp - - - 3 - - - - - INS_simple - - - 4 - - - - - ISC_TapPos_ATCC - - - 8 - - - - - ISC_TapPos_YLTC - - - 5 - - - - - LPL_LD - - - 5 - - - - - LPL_noLD - - - 4 - - - - - MV_db_int - - - 9 - - - - - MV_int - - - 5 - - - - - MV_db_float - - - 8 - - - - - MV_float - - - 3 - - - - - ORG_GrRef - - - 1 - - - - - SAV_AmpSv_TCTR - - - 5 - - - - - SAV_VolSv_TVTR - - - 5 - - - - - SPC_statusonly - - - 4 - - - - - SPC_Auto_ATCC - - - 7 - - - - - SPC_LocSta - - - 7 - - - - - SPS_simple - - - 4 - - - - - WYE_phases - - - 3 - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot DOType wizards defines a createDOTypeWizard looks like the latest snapshot */ - -snapshots["DOType wizards defines a dOTypeWizard looks like the latest snapshot"] = -` - -
    - - - - - - - - - - stVal - - - #Dummy_Beh - - - - - q - - - Quality - - - - - t - - - Timestamp - - - - - stSeld - - - BOOLEAN - - - - - opRcvd - - - BOOLEAN - - - - - opOk - - - BOOLEAN - - - - - tOpOk - - - Timestamp - - - - - ctlModel - - - #Dummy_ctlModel - - - - - sboTimeout - - - INT32U - - - - - operTimeout - - - INT32U - - - - - SBO - - - ObjRef - - - - - SBOw - - - #Dummy.LLN0.Mod.SBOw - - - - - Oper - - - #Dummy.LLN0.Mod.SBOw - - - - - Cancel - - - #Dummy.LLN0.Mod.Cancel - - - -
    - - - - -
    -`; -/* end snapshot DOType wizards defines a dOTypeWizard looks like the latest snapshot */ - -snapshots["DOType wizards defines a sDOWizard to edit an existing SDO looks like the latest snapshot"] = -` - -
    - - > - - - - - - Dummy.LLN0.Mod - - - Dummy.LLN0.Beh - - - Dummy.LLN0.Health - - - Dummy.LLN0.NamPlt - - - Dummy.LPHD1.PhyNam - - - Dummy.LPHD1.Sim - - - Dummy.XCBR1.Pos - - - Dummy.CSWI.Pos1 - - - Dummy.CSWI.Pos2 - - - Dummy.XCBR1.OpCnt - - - Dummy.XCBR1.NamPlt - - - Dummy.XCBR1.BlkOpn - - - Dummy.SPS - - - Dummy.WYE - - - Dummy.CMV - - -
    - - - - -
    -`; -/* end snapshot DOType wizards defines a sDOWizard to edit an existing SDO looks like the latest snapshot */ - -snapshots["DOType wizards defines a sDOWizard to create a new SDO element looks like the latest snapshot"] = -` -
    - - > - - - - - - Dummy.LLN0.Mod - - - Dummy.LLN0.Beh - - - Dummy.LLN0.Health - - - Dummy.LLN0.NamPlt - - - Dummy.LPHD1.PhyNam - - - Dummy.LPHD1.Sim - - - Dummy.XCBR1.Pos - - - Dummy.CSWI.Pos1 - - - Dummy.CSWI.Pos2 - - - Dummy.XCBR1.OpCnt - - - Dummy.XCBR1.NamPlt - - - Dummy.XCBR1.BlkOpn - - - Dummy.SPS - - - Dummy.WYE - - - Dummy.CMV - - -
    - - - - -
    -`; -/* end snapshot DOType wizards defines a sDOWizard to create a new SDO element looks like the latest snapshot */ - diff --git a/packages/plugins/test/integration/editors/templates/__snapshots__/enumtype-wizarding.test.snap.js b/packages/plugins/test/integration/editors/templates/__snapshots__/enumtype-wizarding.test.snap.js deleted file mode 100644 index 73368af11c..0000000000 --- a/packages/plugins/test/integration/editors/templates/__snapshots__/enumtype-wizarding.test.snap.js +++ /dev/null @@ -1,1648 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["EnumType wizards defines a createEnumTypeWizard looks like the latest snapshot"] = -` -
    - - - - BehaviourModeKind - - - 5 - - - - - CtlModelKind - - - 5 - - - - - OpenSCD_StatusOnly - - - 1 - - - - - OriginatorCategoryKind - - - 9 - - - - - MultiplierKind - - - 21 - - - - - AngleReferenceKind - - - 4 - - - - - CurveCharKind - - - 17 - - - - - FaultDirectionKind - - - 4 - - - - - HvReferenceKind - - - 3 - - - - - MonthKind - - - 13 - - - - - OccurrenceKind - - - 5 - - - - - OutputSignalKind - - - 3 - - - - - PeriodKind - - - 5 - - - - - PhaseAngleReferenceKind - - - 12 - - - - - PhaseFaultDirectionKind - - - 3 - - - - - PhaseReferenceKind - - - 4 - - - - - RangeKind - - - 5 - - - - - SIUnitKind - - - 77 - - - - - SboClassKind - - - 2 - - - - - SequenceKind - - - 2 - - - - - SeverityKind - - - 5 - - - - - WeekdayKind - - - 8 - - - - - AdjustmentKind - - - 4 - - - - - AffectedPhasesKind - - - 8 - - - - - AutoReclosingKind - - - 12 - - - - - BreakerOpCapabilityKind - - - 7 - - - - - CalcIntervalKind - - - 8 - - - - - CalcMethodKind - - - 13 - - - - - CalcModeKind - - - 3 - - - - - ClockSourceKind - - - 5 - - - - - ClockSyncKind - - - 3 - - - - - ClockSyncLockingKind - - - 5 - - - - - DirectionModeKind - - - 3 - - - - - FailureDetectionKind - - - 4 - - - - - FaultLoopKind - - - 7 - - - - - FaultMeasuredValueTypeKind - - - 3 - - - - - FilterFunctionKind - - - 5 - - - - - FuseFunctionKind - - - 6 - - - - - HealthKind - - - 3 - - - - - InstrumentTransformerMeasurementRatingKind - - - 9 - - - - - InstrumentTransformerProtectionRatingKind - - - 5 - - - - - LeapSecondKind - - - 4 - - - - - LevelTriggerModeKind - - - 4 - - - - - LiveDeadModeKind - - - 7 - - - - - MaterialKind - - - 11 - - - - - MaterialStateKind - - - 5 - - - - - PFSignKind - - - 2 - - - - - PIDAlgorithmKind - - - 7 - - - - - POWSwitchingCapabilityKind - - - 4 - - - - - ParallelCoilModeKind - - - 4 - - - - - ParallelCtrlModeKind - - - 3 - - - - - ParallelTransfModeKind - - - 8 - - - - - PolarizingQuantityKind - - - 7 - - - - - RecordingModeKind - - - 2 - - - - - RectifierControlModeKind - - - 3 - - - - - ResetCurveKind - - - 3 - - - - - RestraintModeKind - - - 9 - - - - - RetripModeKind - - - 6 - - - - - RotatingMachineStateKind - - - 5 - - - - - RotationalDirectionKind - - - 3 - - - - - RotorThermalStateKind - - - 3 - - - - - SOFEnablingModeKind - - - 3 - - - - - SOFOperationModeKind - - - 3 - - - - - STotalCalcMethodKind - - - 2 - - - - - ScheduleEnablingErrorKind - - - 7 - - - - - ScheduleStateKind - - - 4 - - - - - SetpointEndKind - - - 16 - - - - - StageControlKind - - - 4 - - - - - SwitchFunctionKind - - - 4 - - - - - SwitchingCapabilityKind - - - 4 - - - - - SynchOperationModeKind - - - 4 - - - - - TankFillKind - - - 3 - - - - - TransientPerformanceClassKind - - - 9 - - - - - TpcAppModeKind - - - 6 - - - - - TriggerSourceKind - - - 3 - - - - - TripBehaviourKind - - - 3 - - - - - TripModeKind - - - 4 - - - - - TuningKind - - - 6 - - - - - UnbalanceDetectionKind - - - 6 - - - - - UnblockModeKind - - - 3 - - - - - VoltInterruptDetectionKind - - - 8 - - - - - WeakEndInfeedModeKind - - - 4 - - - - - - - -
    - - - - -
    -`; -/* end snapshot EnumType wizards defines a createEnumTypeWizard looks like the latest snapshot */ - -snapshots["EnumType wizards defines an eNumTypeEditWizard looks like the latest snapshot"] = -` - -
    - - - - - - - - status-only - - - 0 - - - - - direct-with-normal-security - - - 1 - - - - - sbo-with-normal-security - - - 2 - - - - - direct-with-enhanced-security - - - 3 - - - - - sbo-with-enhanced-security - - - 4 - - - -
    - - - - -
    -`; -/* end snapshot EnumType wizards defines an eNumTypeEditWizard looks like the latest snapshot */ - -snapshots["EnumType wizards defines a eNumValWizard to edit an existing EnumVal looks like the latest snapshot"] = -` - -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot EnumType wizards defines a eNumValWizard to edit an existing EnumVal looks like the latest snapshot */ - -snapshots["EnumType wizards defines a eNumValWizard to create a new EnumVal element looks like the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot EnumType wizards defines a eNumValWizard to create a new EnumVal element looks like the latest snapshot */ - diff --git a/packages/plugins/test/integration/editors/templates/__snapshots__/lnodetype-wizard.test.snap.js b/packages/plugins/test/integration/editors/templates/__snapshots__/lnodetype-wizard.test.snap.js deleted file mode 100644 index 2f56575d35..0000000000 --- a/packages/plugins/test/integration/editors/templates/__snapshots__/lnodetype-wizard.test.snap.js +++ /dev/null @@ -1,4882 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["LNodeType wizards defines a lNodeTypeHelperWizard looks like the latest snapshot"] = -` - -
    - - - - - - - - - - Beh - - - #Dummy.LLN0.Beh - - - - - NamPlt - - - #Dummy.XCBR1.NamPlt - - - - - Loc - - - #Dummy.SPS - - - - - OpCnt - - - #Dummy.XCBR1.OpCnt - - - - - Pos - - - #Dummy.CSWI.Pos1 - - - -
    - - - - -
    -`; -/* end snapshot LNodeType wizards defines a lNodeTypeHelperWizard looks like the latest snapshot */ - -snapshots["LNodeType wizards defines a dOWizard to create a new DO element looks like the latest snapshot"] = -` -
    - - > - - - - - - Dummy.LLN0.Mod - - - Dummy.LLN0.Beh - - - Dummy.LLN0.Health - - - Dummy.LLN0.NamPlt - - - Dummy.LPHD1.PhyNam - - - Dummy.LPHD1.Sim - - - Dummy.XCBR1.Pos - - - Dummy.CSWI.Pos1 - - - Dummy.CSWI.Pos2 - - - Dummy.XCBR1.OpCnt - - - Dummy.XCBR1.NamPlt - - - Dummy.XCBR1.BlkOpn - - - Dummy.SPS - - - Dummy.WYE - - - Dummy.CMV - - - - - - -
    - - - - -
    -`; -/* end snapshot LNodeType wizards defines a dOWizard to create a new DO element looks like the latest snapshot */ - -snapshots["LNodeType wizards defines a createLNodeTypeWizard looks like the latest snapshot"] = -` -
    - - - Pre-defined lnClasses from templates - -
  • -
  • - - - ATCC - - - Auto Tap changer controller: no process bus(PB) - - - 11 - - - - - ATCC - - - Auto Tap changer controller: process bus - - - 14 - - - - - CSWI - - - Switch control: no process bus(PB) - - - 7 - - - - - CSWI - - - Switch control: three phase - - - 11 - - - - - CSWI - - - Switch control: single phase - - - 15 - - - - - CILO - - - Interlocking - - - 6 - - - - - LLN0 - - - Logical device LN: referenced - - - 7 - - - - - LLN0 - - - Logical device LN: parent - - - 6 - - - - - LPHD - - - Physical device - - - 6 - - - - - MMXU - - - Three phase measurement - - - 14 - - - - - PTRC - - - Trip conditioning: General trip signal - - - 7 - - - - - RSYC - - - Synchronism check - - - 7 - - - - - TCTR - - - Current transformer - - - 7 - - - - - TVTR - - - Voltage transformer - - - 7 - - - - - XSWI - - - Switch: no process bus(PB) - - - 11 - - - - - XSWI - - - Switch: three phase represenation - - - 12 - - - - - XSWI - - - Switch: one phase represenation - - - 11 - - - - - XCBR - - - Circuit Breaker: no process bus(PB) - - - 10 - - - - - XCBR - - - Circuit Breaker: one phase representation - - - 10 - - - - - XCBR - - - Circuit Breaker: three phase representation - - - 11 - - - - - YLTC - - - Tap changer - - - 10 - - - - Empty lnClasses from IEC 61850-7-4 - -
  • -
  • - - - LPHD - - - 16 - - - - - LLN0 - - - 13 - - - - - LCCH - - - 17 - - - - - LGOS - - - 13 - - - - - LSVS - - - 12 - - - - - LTIM - - - 13 - - - - - LTMS - - - 14 - - - - - LTRK - - - 23 - - - - - ANCR - - - 54 - - - - - ARCO - - - 30 - - - - - ARIS - - - 32 - - - - - ATCC - - - 71 - - - - - AVCO - - - 33 - - - - - CALH - - - 24 - - - - - CCGR - - - 51 - - - - - CILO - - - 22 - - - - - CPOW - - - 29 - - - - - CSWI - - - 35 - - - - - CSYN - - - 82 - - - - - FCNT - - - 23 - - - - - FCSD - - - 22 - - - - - FFIL - - - 32 - - - - - FLIM - - - 25 - - - - - FPID - - - 35 - - - - - FRMP - - - 27 - - - - - FSCC - - - 13 - - - - - FSCH - - - 28 - - - - - FSPT - - - 40 - - - - - FXOT - - - 25 - - - - - FXUT - - - 25 - - - - - GAPC - - - 35 - - - - - GGIO - - - 38 - - - - - GLOG - - - 24 - - - - - GSAL - - - 26 - - - - - IARC - - - 29 - - - - - IHMI - - - 24 - - - - - ISAF - - - 24 - - - - - ITCI - - - 25 - - - - - ITMI - - - 21 - - - - - ITPC - - - 42 - - - - - KFAN - - - 33 - - - - - KFIL - - - 36 - - - - - KPMP - - - 33 - - - - - KTNK - - - 27 - - - - - KVLV - - - 44 - - - - - MENV - - - 32 - - - - - MFLK - - - 38 - - - - - MFLW - - - 35 - - - - - MHAI - - - 59 - - - - - MHAN - - - 53 - - - - - MHET - - - 30 - - - - - MHYD - - - 28 - - - - - MMDC - - - 28 - - - - - MMET - - - 42 - - - - - MMTN - - - 27 - - - - - MMTR - - - 27 - - - - - MMXN - - - 28 - - - - - MMXU - - - 63 - - - - - MSQI - - - 33 - - - - - PDIF - - - 38 - - - - - PDIR - - - 27 - - - - - PDIS - - - 48 - - - - - PDOP - - - 30 - - - - - PDUP - - - 30 - - - - - PFRC - - - 31 - - - - - PHAR - - - 30 - - - - - PHIZ - - - 31 - - - - - PIOC - - - 27 - - - - - PMRI - - - 34 - - - - - PMSS - - - 30 - - - - - POPF - - - 33 - - - - - PPAM - - - 27 - - - - - PRTR - - - 27 - - - - - PSCH - - - 42 - - - - - PSDE - - - 33 - - - - - PSOF - - - 36 - - - - - PTDV - - - 28 - - - - - PTEF - - - 29 - - - - - PTHF - - - 27 - - - - - PTOC - - - 37 - - - - - PTOF - - - 31 - - - - - PTOV - - - 35 - - - - - PTRC - - - 29 - - - - - PTTR - - - 48 - - - - - PTUC - - - 37 - - - - - PTUF - - - 31 - - - - - PTUV - - - 35 - - - - - PUPF - - - 33 - - - - - PVOC - - - 38 - - - - - PVPH - - - 36 - - - - - PZSU - - - 29 - - - - - QFVR - - - 30 - - - - - QITR - - - 27 - - - - - QIUB - - - 28 - - - - - QVTR - - - 27 - - - - - QVUB - - - 28 - - - - - QVVR - - - 34 - - - - - RADR - - - 30 - - - - - RBDR - - - 28 - - - - - RBRF - - - 30 - - - - - RDIR - - - 30 - - - - - RDRE - - - 40 - - - - - RDRS - - - 22 - - - - - RFLO - - - 24 - - - - - RMXU - - - 25 - - - - - RPSB - - - 34 - - - - - RREC - - - 35 - - - - - RSYN - - - 58 - - - - - SARC - - - 25 - - - - - SCBR - - - 56 - - - - - SIMG - - - 33 - - - - - SIML - - - 52 - - - - - SLTC - - - 28 - - - - - SOPM - - - 40 - - - - - SPDC - - - 29 - - - - - SPRS - - - 31 - - - - - SPTR - - - 31 - - - - - SSWI - - - 48 - - - - - STMP - - - 31 - - - - - SVBR - - - 32 - - - - - TANG - - - 26 - - - - - TAXD - - - 26 - - - - - TCTR - - - 39 - - - - - TDST - - - 26 - - - - - TFLW - - - 26 - - - - - TFRQ - - - 26 - - - - - TGSN - - - 26 - - - - - THUM - - - 26 - - - - - TLVL - - - 26 - - - - - TMGF - - - 26 - - - - - TMVM - - - 26 - - - - - TPOS - - - 26 - - - - - TPRS - - - 26 - - - - - TRTN - - - 26 - - - - - TSND - - - 26 - - - - - TTMP - - - 26 - - - - - TTNS - - - 26 - - - - - TVBR - - - 26 - - - - - TVTR - - - 36 - - - - - TWPH - - - 26 - - - - - XCBR - - - 40 - - - - - XFUS - - - 27 - - - - - XSWI - - - 35 - - - - - YEFN - - - 39 - - - - - YLTC - - - 36 - - - - - YPSH - - - 33 - - - - - YPTR - - - 37 - - - - - ZAXN - - - 25 - - - - - ZBAT - - - 32 - - - - - ZBSH - - - 32 - - - - - ZCAB - - - 36 - - - - - ZCAP - - - 25 - - - - - ZCON - - - 25 - - - - - ZGEN - - - 42 - - - - - ZGIL - - - 23 - - - - - ZLIN - - - 36 - - - - - ZMOT - - - 30 - - - - - ZREA - - - 27 - - - - - ZRES - - - 23 - - - - - ZRRC - - - 31 - - - - - ZSAR - - - 25 - - - - - ZSCR - - - 30 - - - - - ZSMC - - - 59 - - - - - ZTCF - - - 24 - - - - - ZTCR - - - 23 - - - - Empty lnClasses from IEC 61850-7-420 - -
  • -
  • - - - DECP - - - 38 - - - - - DPCC - - - 40 - - - - - DVER - - - 24 - - - - - DPMC - - - 60 - - - - - DMDR - - - 92 - - - - - DGEN - - - 156 - - - - - DSTO - - - 181 - - - - - DLOD - - - 117 - - - - - SBAT - - - 76 - - - - - DBAT - - - 71 - - - - - DPVA - - - 32 - - - - - DPVM - - - 36 - - - - - DPVC - - - 38 - - - - - DTRC - - - 50 - - - - - DCIP - - - 80 - - - - - DFCL - - - 53 - - - - - DSTK - - - 41 - - - - - DFPM - - - 28 - - - - - KFUL - - - 35 - - - - - KFLV - - - 42 - - - - - DCHC - - - 38 - - - - - DCTS - - - 27 - - - - - DCHB - - - 33 - - - - - DEXC - - - 55 - - - - - DINV - - - 63 - - - - - DRTF - - - 45 - - - - - SINV - - - 26 - - - - - DCCT - - - 36 - - - - - DCST - - - 27 - - - - - MMET - - - 42 - - - - - MMXU - - - 63 - - - - - DCTE - - - 50 - - - - - DHVT - - - 45 - - - - - DLVT - - - 45 - - - - - DHFT - - - 46 - - - - - DLFT - - - 46 - - - - - DHFW - - - 70 - - - - - DLFW - - - 70 - - - - - DAGC - - - 61 - - - - - DTCD - - - 66 - - - - - DVWC - - - 68 - - - - - DWFL - - - 63 - - - - - DWGC - - - 59 - - - - - DWMN - - - 56 - - - - - DWMX - - - 56 - - - - - DFPF - - - 59 - - - - - DVVR - - - 66 - - - - - DVAR - - - 58 - - - - - DWVR - - - 60 - - - - - DRGS - - - 74 - - -
    - - - - -
    - - - - -
    -`; -/* end snapshot LNodeType wizards defines a createLNodeTypeWizard looks like the latest snapshot */ - -snapshots["LNodeType wizards defines a createLNodeTypeWizard opens a createLNodeTypeHelperWizard looks like the latest snapshot"] = -` -
    - - - Dummy.LLN0.NamPlt - - - Dummy.XCBR1.NamPlt - - - - - Dummy.LLN0.Beh - - - Dummy.LLN0.Health - - - - - Dummy.LLN0.Health - - - Dummy.LLN0.Beh - - - - - Dummy.SPS - - - - - Dummy.LLN0.Mod - - - - - - - Dummy.SPS - - - - - Dummy.XCBR1.OpCnt - - - - - Dummy.LPHD1.Sim - - - Dummy.XCBR1.BlkOpn - - - - - - - - - - - - - - - - - - - - - - - Dummy.SPS - - - - - - - Dummy.SPS - - - - - Dummy.SPS - - -
    - - - - -
    -`; -/* end snapshot LNodeType wizards defines a createLNodeTypeWizard opens a createLNodeTypeHelperWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/integration/editors/templates/datype-wizarding.test.ts b/packages/plugins/test/integration/editors/templates/datype-wizarding.test.ts deleted file mode 100644 index 3d0c5d644d..0000000000 --- a/packages/plugins/test/integration/editors/templates/datype-wizarding.test.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { html, fixture, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-open-scd.js'; - -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { Select } from '@material/mwc-select'; - -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import TemplatesPlugin from '../../../../src/editors/Templates.js'; -import { patterns } from '@openscd/open-scd/src/foundation.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -describe('DAType wizards', () => { - if (customElements.get('templates-editor') === undefined) - customElements.define('templates-editor', TemplatesPlugin); - let doc: Document; - let parent: MockOpenSCD; - let templates: TemplatesPlugin; - let dATypeList: FilteredList; - - beforeEach(async () => { - parent = await fixture( - html`` - ); - - templates = parent.getActivePlugin(); - - doc = await fetch('/test/testfiles/templates/datypes.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - templates.doc = doc; - await templates.updateComplete; - dATypeList = ( - templates.shadowRoot?.querySelector('filtered-list[id="datypelist"]') - ); - }); - - describe('defines a createDATypeWizard', () => { - let selector: Select; - let idField: WizardTextField; - let primayAction: HTMLElement; - beforeEach(async () => { - const button = ( - templates?.shadowRoot?.querySelectorAll( - 'mwc-icon-button[icon="playlist_add"]' - )[2] - ); - button.click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - selector = ( - parent.wizardUI.dialog?.querySelector('mwc-select[label="values"]') - ); - idField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="id"]') - ); - cdcField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="cdc"]') - ); - primayAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - // prettier does not support escaping in regexes of the /v flag - await expect(parent.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - // work around, because the escapes get removed in snapshot by prettier - it('should have correct pattern', async () => { - expect( - parent.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]')! - .length - ).to.equal(3); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.nmToken); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[2] - .getAttribute('pattern') - ).to.equal(patterns.cdc); - }); - - it('allows to add empty DOTypes to the project', async () => { - expect(doc.querySelector('DOType[id="myGeneralDOType"]')).to.not.exist; - idField.maybeValue = 'myGeneralDOType'; - cdcField.maybeValue = 'SPS'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('DOType[id="myGeneralDOType"]')).to.exist; - }); - - it('allows to define CDC only for empty DOType creation', async () => { - await cdcField.updateComplete; - expect(cdcField.disabled).to.not.be.true; - selector.value = 'OpenSCD_ENS_Health'; - await cdcField.requestUpdate(); - expect(cdcField.disabled).to.be.true; - }); - - it('requires CDC definition for empty DOTypes', async () => { - expect(doc.querySelector('DOType[id="myGeneralDOType"]')).to.not.exist; - idField.maybeValue = 'myGeneralDOType'; - cdcField.maybeValue = null; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('DOType[id="myGeneralDOType"]')).to.not.exist; - }); - - it('respects the sequence defined in the standard', async () => { - idField.maybeValue = 'myGeneralDOType'; - cdcField.maybeValue = 'SPS'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - const element = doc.querySelector('DOType[id="myGeneralDOType"]'); - expect(element?.nextElementSibling?.tagName).to.equal('DOType'); - expect(element?.previousElementSibling?.tagName).to.equal('LNodeType'); - }); - - it('recursively add missing! subsequent EnumType elements', async () => { - expect(doc.querySelector('DOType[id="myENSHealth"]')).to.not.exist; - expect(doc.querySelector('EnumType[id="HealthKind"]')).to.not.exist; - selector.value = 'OpenSCD_ENS_Health'; - idField.maybeValue = 'myENSHealth'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('DOType[id="myENSHealth"]')).to.exist; - expect(doc.querySelector('EnumType[id="HealthKind"]')).to.exist; - expect(doc.querySelectorAll('EnumType[id="HealthKind"]').length).to.equal( - 1 - ); - }); - - it('recursively add missing! subsequent DAType elements', async () => { - expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_INT32"]')).to - .not.exist; - selector.value = 'OpenSCD_MV_int'; - idField.maybeValue = 'myMV'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('DAType[id="OpenSCD_AnalogueValue_INT32"]')).to - .exist; - expect( - doc.querySelectorAll('DAType[id="OpenSCD_AnalogueValue_INT32"]').length - ).to.equal(1); - }); - }); - - describe('defines a dOTypeWizard', () => { - let idField: WizardTextField; - let primayAction: HTMLElement; - let deleteButton: HTMLElement; - - beforeEach(async () => { - (( - dOTypeList.querySelector('mwc-list-item[value="#Dummy.LLN0.Mod"]') - )).click(); - await parent.requestUpdate(); - await new Promise(resolve => setTimeout(resolve, 100)); //recursive call takes time - idField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="id"]') - ); - primayAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - deleteButton = ( - Array.from( - parent.wizardUI.dialog!.querySelectorAll( - 'mwc-menu > mwc-list-item' - ) - ).find(item => item.innerHTML.includes(`Remove`)) - ); - }); - - it('looks like the latest snapshot', async () => { - // prettier does not support escaping in regexes of the /v flag - await expect(parent.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - // work around, because the escapes get removed in snapshot by prettier - it('should have correct pattern', async () => { - expect( - parent.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]')! - .length - ).to.equal(3); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.nmToken); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[2] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - }); - - it('edits DOType attributes id', async () => { - expect(doc.querySelector('DOType[id="Dummy.LLN0.Mod"]')).to.exist; - idField.value = 'changedDOType'; - await parent.requestUpdate(); - primayAction.click(); - await parent.requestUpdate(); - expect(doc.querySelector('DOType[id="Dummy.LLN0.Mod"]')).to.not.exist; - expect(doc.querySelector('DOType[id="changedDOType"]')).to.exist; - }); - - it('deletes the DOType attribute on delete button click', async () => { - expect(doc.querySelector('DOType[id="Dummy.LLN0.Mod"]')).to.exist; - expect(doc.querySelectorAll('DOType').length).to.equal(15); - deleteButton.click(); - await parent.requestUpdate(); - expect(doc.querySelector('DAType[id="Dummy.LLN0.Mod"]')).to.not.exist; - expect(doc.querySelectorAll('DOType').length).to.equal(14); - }); - - it('does not edit DOType element without changes', async () => { - const originData = (( - doc.querySelector('DOType[id="Dummy.LLN0.Mod"]') - )).cloneNode(true); - primayAction.click(); - await parent.requestUpdate(); - expect( - originData.isEqualNode(doc.querySelector('DOType[id="Dummy.LLN0.Mod"]')) - ).to.be.true; - }); - }); - - describe('defines a sDOWizard to edit an existing SDO', () => { - let nameField: WizardTextField; - let primayAction: HTMLElement; - let deleteButton: HTMLElement; - let typeSelect: Select; - - beforeEach(async () => { - (( - dOTypeList.querySelector('mwc-list-item[value="#Dummy.WYE"]') - )).click(); - await parent.requestUpdate(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI?.dialog?.querySelector( - 'mwc-list-item[value="#Dummy.WYE>phsA"]' - ) - )).click(); - await parent.requestUpdate(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - primayAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - deleteButton = ( - parent.wizardUI.dialog?.querySelector('mwc-menu > mwc-list-item') - ); - typeSelect = ( - parent.wizardUI.dialog?.querySelector('mwc-select[label="type"]') - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - // prettier does not support escaping in regexes of the /v flag - await expect(parent.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - // work around, because the escapes get removed in snapshot by prettier - it('should have correct pattern', async () => { - expect( - parent.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]')! - .length - ).to.equal(2); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.tRestrName1stL); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - }); - - it('creates a new SDO element', async () => { - expect( - doc.querySelector( - 'DOType[id="Dummy.LLN0.Mod"] > SDO[name="newSDOElement"]' - ) - ).to.not.exist; - nameField.value = 'newSDOElement'; - typeSelect.value = 'Dummy.CMV'; - await parent.requestUpdate(); - primaryAction.click(); - await parent.requestUpdate(); - expect( - doc.querySelector( - 'DOType[id="Dummy.LLN0.Mod"] > SDO[name="newSDOElement"]:not([desc])[type="Dummy.CMV"]' - ) - ).to.exist; - }); - - it('creates yet another new SDO element', async () => { - const name = 'newSDOElement2'; - const desc = 'newSDOdesc'; - - expect( - doc.querySelector( - 'DOType[id="#Dummy.LLN0.Mod"] > SDO[name="newSDOElement2"]' - ) - ).to.not.exist; - nameField.value = name; - descField.nullable = false; - descField.value = desc; - typeSelect.value = 'Dummy.CMV'; - - await parent.requestUpdate(); - primaryAction.click(); - await parent.requestUpdate(); - expect( - doc.querySelector( - `DOType[id="Dummy.LLN0.Mod"] >` + - `SDO[name="${name}"][desc="${desc}"][type="Dummy.CMV"]` - ) - ).to.exist; - }); - }); -}); diff --git a/packages/plugins/test/integration/editors/templates/enumtype-wizarding.test.ts b/packages/plugins/test/integration/editors/templates/enumtype-wizarding.test.ts deleted file mode 100644 index e7e9af814d..0000000000 --- a/packages/plugins/test/integration/editors/templates/enumtype-wizarding.test.ts +++ /dev/null @@ -1,406 +0,0 @@ -import { html, fixture, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-open-scd.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -import { ListItem } from '@material/mwc-list/mwc-list-item'; -import { Select } from '@material/mwc-select'; - -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; -import TemplatesPlugin from '../../../../src/editors/Templates.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { patterns } from '@openscd/open-scd/src/foundation.js'; - -describe('EnumType wizards', () => { - if (customElements.get('templates-editor') === undefined) - customElements.define('templates-editor', TemplatesPlugin); - let doc: Document; - let parent: MockOpenSCD; - let templates: TemplatesPlugin; - let eNumTypeList: FilteredList; - - beforeEach(async () => { - parent = await fixture( - html`` - ); - - templates = parent.getActivePlugin(); - - doc = await fetch('/test/testfiles/templates/datypes.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - templates.doc = doc; - await templates.updateComplete; - eNumTypeList = ( - templates.shadowRoot?.querySelector('filtered-list[id="enumtypelist"]') - ); - }); - - describe('defines a createEnumTypeWizard', () => { - let selector: Select; - let idField: WizardTextField; - let primayAction: HTMLElement; - beforeEach(async () => { - const button = ( - templates?.shadowRoot?.querySelectorAll( - 'mwc-icon-button[icon="playlist_add"]' - )[3] - ); - button.click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - selector = ( - 'mwc-select[label="lnClass"]' - )!; - idField = parent.wizardUI.dialog!.querySelector( - 'wizard-textfield[label="id"]' - )!; - primayAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - //work around, because the escapes get removed in snapshot - it('should have correct pattern', async () => { - const pattern = - '([:_A-Za-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]' + - '|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]' + - '|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|[.0-9\\-]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040])+'; - expect( - parent.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]')! - .length - ).to.equal(2); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(pattern); - - expect( - parent.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - }); - - it('uses -7-4 and -7-420 namespace for lnClass suggestion', () => - expect( - selector.items.filter(item => !item.noninteractive && !item.twoline) - ).to.have.lengthOf(215)); - - it('recursively add missing! subsequent DOType elements', async () => { - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_ENC_Mod"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_ENS_Beh"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_ENS_Health"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_LPL_noLD"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_SPS_simple"]')).to.not.exist; - expect(doc.querySelector('DOType[id="OpenSCD_DPC"]')).to.not.exist; - await new Promise(resolve => setTimeout(resolve, 100)); //recursive call takes time - selector.value = '#OpenSCD_CSWI_noPB'; - await parent.requestUpdate(); // selector updates autoimport - idField.maybeValue = 'myCSWI'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.exist; - expect( - doc.querySelectorAll('DOType[id="OpenSCD_ENC_Mod"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DOType[id="OpenSCD_ENS_Beh"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DOType[id="OpenSCD_ENS_Health"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DOType[id="OpenSCD_LPL_noLD"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DOType[id="OpenSCD_SPS_simple"]').length - ).to.equal(1); - expect(doc.querySelectorAll('DOType[id="OpenSCD_DPC"]').length).to.equal( - 1 - ); - }).timeout(5000); - - it('recursively add missing! subsequent DAType elements', async () => { - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.not.exist; - expect(doc.querySelector('DAType[id="OpenSCD_Originator"]')).to.not.exist; - expect(doc.querySelector('DAType[id="OpenSCD_OperSBOw_Dbpos"]')).to.not - .exist; - expect(doc.querySelector('DAType[id="OpenSCD_Cancel_Dbpos"]')).to.not - .exist; - expect( - doc.querySelector('DAType[id="OpenSCD_OperSBOw_BehaviourModeKind"]') - ).to.not.exist; - expect(doc.querySelector('DAType[id="OpenSCD_Cancel_BehaviourModeKind"]')) - .to.not.exist; - expect(doc.querySelector('DAType[id="OpenSCD_PulseConfig"]')).to.not - .exist; - selector.value = '#OpenSCD_CSWI_noPB'; - await parent.requestUpdate(); // selector updates autoimport - idField.maybeValue = 'myCSWI'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.exist; - expect( - doc.querySelectorAll('DAType[id="OpenSCD_Originator"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DAType[id="OpenSCD_OperSBOw_Dbpos"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DAType[id="OpenSCD_Cancel_Dbpos"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('DAType[id="OpenSCD_OperSBOw_BehaviourModeKind"]') - .length - ).to.equal(1); - expect( - doc.querySelectorAll('DAType[id="OpenSCD_Cancel_BehaviourModeKind"]') - .length - ).to.equal(1); - expect( - doc.querySelectorAll('DAType[id="OpenSCD_PulseConfig"]').length - ).to.equal(1); - }).timeout(5000); - - it('recursively add missing! subsequent EnumType elements', async () => { - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.not.exist; - expect(doc.querySelector('EnumType[id="OriginatorCategoryKind"]')).to.not - .exist; - expect(doc.querySelector('EnumType[id="BehaviourModeKind"]')).to.not - .exist; - expect(doc.querySelector('EnumType[id="CtlModelKind"]')).to.not.exist; - expect(doc.querySelector('EnumType[id="HealthKind"]')).to.not.exist; - expect(doc.querySelector('EnumType[id="OutputSignalKind"]')).to.not.exist; - selector.value = '#OpenSCD_CSWI_noPB'; - await parent.requestUpdate(); // selector updates autoimport - idField.maybeValue = 'myCSWI'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - expect(doc.querySelector('LNodeType[id="myCSWI"]')).to.exist; - expect( - doc.querySelectorAll('EnumType[id="OriginatorCategoryKind"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('EnumType[id="BehaviourModeKind"]').length - ).to.equal(1); - expect( - doc.querySelectorAll('EnumType[id="CtlModelKind"]').length - ).to.equal(1); - expect(doc.querySelectorAll('EnumType[id="HealthKind"]').length).to.equal( - 1 - ); - expect( - doc.querySelectorAll('EnumType[id="OutputSignalKind"]').length - ).to.equal(1); - }).timeout(5000); - - it('respects the sequence defined in the standard', async () => { - selector.value = '#OpenSCD_CSWI_noPB'; - await parent.requestUpdate(); // selector updates autoimport - idField.maybeValue = 'myGeneralLNodeType'; - await parent.requestUpdate(); - primayAction.click(); - await parent.updateComplete; - const element = doc.querySelector('LNodeType[id="myGeneralLNodeType"]'); - expect(element?.nextElementSibling?.tagName).to.equal('LNodeType'); - expect(element?.previousElementSibling).to.be.null; - }).timeout(5000); - - describe('opens a createLNodeTypeHelperWizard', () => { - let saveButton: HTMLElement; - let beh: Select; - let enaOpn: Select; - let enaCls: Select; - let ens: Element; - let sps: Element; - let ensId: string; - let spsId: string; - - beforeEach(async () => { - selector.value = 'CILO'; - idField.maybeValue = 'myGeneralLNodeType'; - await parent.updateComplete; - - (( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - )).click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 400)); // await animation - - saveButton = parent.wizardUI.shadowRoot!.querySelector( - 'mwc-button[slot="primaryAction"]' - )!; - - beh = parent.wizardUI.shadowRoot!.querySelector( - 'wizard-select:nth-child(21)' - )!; - enaCls = parent.wizardUI.shadowRoot!.querySelector( - parent.wizardUI.dialog?.querySelector('mwc-select[label="type"]') - ); - transientSelect = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="transient"]' - ) - ); - primaryAction = ( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - deleteButton = ( - parent.wizardUI.dialog?.querySelector('mwc-menu > mwc-list-item') - ); - }); - - it('looks like the latest snapshot', () => { - expect(parent.wizardUI.dialog).to; - }); - it('edits DO attributes name', async () => { - expect(doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]')) - .to.exist; - nameField.value = 'NewMod'; - await parent.requestUpdate(); - primaryAction.click(); - await parent.requestUpdate(); - expect(doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]')) - .to.not.exist; - expect( - doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="NewMod"]') - ).to.exist; - }); - it('edits yet another attribute of the DO element', async () => { - expect( - doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="NewMod"]') - ).to.not.exist; - - nameField.value = 'NewMod'; - descField.nullable = false; - descField.value = 'myDesc'; - typeSelect.value = 'Dummy.CMV'; - accessControlField.nullable = false; - accessControlField.maybeValue = 'myAccessControl'; - transientSelect.maybeValue = 'true'; - - await parent.requestUpdate(); - primaryAction.click(); - await parent.requestUpdate(); - expect( - doc.querySelector( - `LNodeType[id="Dummy.LLN0"] >` + - `DO[name="NewMod"][desc="myDesc"][type="Dummy.CMV"][accessControl="myAccessControl"][transient="true"]` - ) - ).to.exist; - }); - it('deletes the DO element on delete button click', async () => { - expect(doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]')) - .to.exist; - expect( - doc.querySelectorAll('LNodeType[id="Dummy.LLN0"] > DO').length - ).to.equal(4); - deleteButton.click(); - await parent.requestUpdate(); - expect(doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]')) - .to.not.exist; - expect( - doc.querySelectorAll('LNodeType[id="Dummy.LLN0"] > DO').length - ).to.equal(3); - }); - it('does not edit DO element without changes', async () => { - const originData = (( - doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]') - )).cloneNode(true); - primaryAction.click(); - await parent.requestUpdate(); - expect( - originData.isEqualNode( - doc.querySelector('LNodeType[id="Dummy.LLN0"] > DO[name="Mod"]') - ) - ).to.be.true; - }); - it('filters the type selector to DOTypes', async () => { - expect(typeSelect!.querySelectorAll('mwc-list-item').length).to.equal( - doc.querySelectorAll('DOType').length - ); - }); - }); - - describe('defines a dOWizard to create a new DO element', () => { - let nameField: WizardTextField; - let descField: WizardTextField; - let typeSelect: Select; - let accessControlField: WizardTextField; - let transientSelect: WizardCheckbox; - let primaryAction: HTMLElement; - - beforeEach(async () => { - (( - lNodeTypeList.querySelector('mwc-list-item[value="#Dummy.LLN0"]') - )).click(); - await parent.requestUpdate(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog?.querySelectorAll('mwc-menu > mwc-list-item')[1] - )).click(); - await parent.requestUpdate(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - nameField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="name"]') - ); - descField = ( - parent.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - accessControlField = ( - parent.wizardUI.dialog?.querySelector( - 'wizard-textfield[label="accessControl"]' - ) - ); - typeSelect = ( - redirectUI.querySelector(`mwc-select[label="${oldIed}"]`) - ); - - if (select) select.value = newIed; - }); - } - - redirectUI - .querySelector('mwc-button[icon="content_copy"]') - ?.click(); - await redirectUI.updateComplete; -} - -describe('Clone Redirection UI', () => { - describe('triggered by bay-editor', () => { - let element: BayEditor; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - const bay = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - element = ( - await fixture(html``) - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - it('looks like the latest snapshot', async () => { - await loadAndClone(element, 'validRedirect.scd'); - - expect(element.dialog).to.exist; - expect(actionEvent).to.not.have.been.called; - await expect(element.dialog).to.equalSnapshot(); - }); - - it('checks for name uniqueness ', async () => { - await loadAndClone(element, 'validRedirect.scd'); - await setUpAndTriggerRedirectUI(element.dialog, 'Q01'); - - expect(actionEvent).to.not.have.been.called; - }); - - it('only redirect selected IEDs', async () => { - await loadAndClone(element, 'validRedirect.scd'); - await setUpAndTriggerRedirectUI(element.dialog, 'Q02', { - IED1: 'IED3', - IED2: 'No', - }); - - const cloneEntity = actionEvent.args[0][0].detail.action.new.element; - expect(cloneEntity.querySelectorAll('LNode').length).to.equal(2); - expect( - cloneEntity.querySelectorAll('LNode:not([iedName="IED3"])').length - ).to.equal(0); - }); - - it('checks reference validity before redirect', async () => { - await loadAndClone(element, 'validRedirect.scd'); - await setUpAndTriggerRedirectUI(element.dialog, 'Q02', { - IED1: 'No', - IED2: 'IED4', - }); - - const cloneEntity = actionEvent.args[0][0].detail.action.new.element; - expect(cloneEntity.querySelectorAll('LNode[lnClass="CSWI"]')).to.not - .exist; - }); - - describe('is not visible to the user', () => { - it('in specification phase (LNode="None")', async () => { - await loadAndClone(element, 'specificationOnly.scd'); - - expect(element.dialog).to.not.exist; - expect(actionEvent).to.have.been.called; - }); - - it('in case LNode are all in use', async () => { - await loadAndClone(element, 'noUnusedLNode.scd'); - - expect(element.dialog).to.not.exist; - expect(actionEvent).to.have.been.called; - }); - - it('in case LNode are not present in all other IEDs', async () => { - await loadAndClone(element, 'refMissmatch.scd'); - - expect(element.dialog).to.not.exist; - expect(actionEvent).to.have.been.called; - }); - }); - }); - - describe('triggered by voltage-level-editor', () => { - let element: VoltageLevelEditor; - - beforeEach(async () => { - const voltageLevel = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await loadAndClone(element, 'validRedirect.scd'); - - expect(element.dialog).to.exist; - await expect(element.dialog).to.equalSnapshot(); - }); - }); - - describe('triggered by substation-editor', () => { - let element: SubstationEditor; - - beforeEach(async () => { - const substation = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await loadAndClone(element, 'validRedirect.scd'); - - expect(element.dialog).to.exist; - await expect(element.dialog).to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/sub-equipment-editor.test.ts b/packages/plugins/test/unit/editors/substation/sub-equipment-editor.test.ts deleted file mode 100644 index 5505cfa279..0000000000 --- a/packages/plugins/test/unit/editors/substation/sub-equipment-editor.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/sub-equipment-editor.js'; -import { SubEquipmentEditor } from '../../../../src/editors/substation/sub-equipment-editor.js'; - -describe('sub-equipment-editor', () => { - let element: SubEquipmentEditor; - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - - describe('With children', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('without description and state', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/sub-function-editor.test.ts b/packages/plugins/test/unit/editors/substation/sub-function-editor.test.ts deleted file mode 100644 index f861502ee9..0000000000 --- a/packages/plugins/test/unit/editors/substation/sub-function-editor.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/sub-function-editor.js'; -import { SubFunctionEditor } from '../../../../src/editors/substation/sub-function-editor.js'; - -describe('web component rendering SubFunction element', () => { - let element: SubFunctionEditor; - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('with complete attribute set and existing children', () => { - beforeEach(async () => { - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with missing desc and type attribute', () => { - beforeEach(async () => { - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with existing LNode children', () => { - beforeEach(async () => { - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with general-equipment children', () => { - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('SubFunction')!; - element.showfunctions = false; - await element.updateComplete; - }); - - it('with showfunctions false looks like the latest snapshot', async () => - await expect(element).shadowDom.to.equalSnapshot()); - - it('with showfunctions true looks like the latest snapshot', async () => { - element.showfunctions = true; - await element.updateComplete; - - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/substation-editor.test.ts b/packages/plugins/test/unit/editors/substation/substation-editor.test.ts deleted file mode 100644 index 220a54889b..0000000000 --- a/packages/plugins/test/unit/editors/substation/substation-editor.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { html, fixture, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/substation-editor.js'; -import { SubstationEditor } from '../../../../src/editors/substation/substation-editor.js'; - -describe('substation-editor', () => { - let element: SubstationEditor; - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = await fixture(html``); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - - describe('with readonly property', () => { - beforeEach(async () => { - element.readonly = true; - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with function filter deactivated', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('Substation')!; - element.showfunctions = true; - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with general-equipment children', () => { - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('Substation')!; - element.showfunctions = false; - await element.updateComplete; - }); - - it('with showfunctions false looks like the latest snapshot', async () => - await expect(element).shadowDom.to.equalSnapshot()); - - it('with showfunctions true looks like the latest snapshot', async () => { - element.showfunctions = true; - await element.updateComplete; - - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/tapchanger-editor.test.ts b/packages/plugins/test/unit/editors/substation/tapchanger-editor.test.ts deleted file mode 100644 index 4b0f00179d..0000000000 --- a/packages/plugins/test/unit/editors/substation/tapchanger-editor.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/tapchanger-editor.js'; -import { TapChangerEditor } from '../../../../src/editors/substation/tapchanger-editor.js'; - -describe('web component rendering TapChanger element', () => { - let element: TapChangerEditor; - let doc: XMLDocument; - - describe('rendering LNode and EqFunction children', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/TapChanger.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - element.showfunctions = true; - await element.updateComplete; - }); - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('rendering SubEquipment', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/editors/substation/TapChanger.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - element.showfunctions = true; - await element.updateComplete; - }); - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/transformer-winding-editor.test.ts b/packages/plugins/test/unit/editors/substation/transformer-winding-editor.test.ts deleted file mode 100644 index 2ed1ada4c5..0000000000 --- a/packages/plugins/test/unit/editors/substation/transformer-winding-editor.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/transformer-winding-editor.js'; -import { TransformerWindingEditor } from '../../../../src/editors/substation/transformer-winding-editor.js'; - -describe('transformer-winding-editor', () => { - let element: TransformerWindingEditor; - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch( - 'test/testfiles/editors/substation/TransformerWinding.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('with children', () => { - describe('when EqFunction elements are rendered', () => { - it('looks like the latest snapshot', async () => { - element = ( - await fixture( - html`` - ) - ); - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - describe('when hiding EqFunction elements', () => { - it('looks like the latest snapshot', async () => { - element = ( - await fixture( - html`` - ) - ); - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - }); - - describe('without children', () => { - it('looks like the latest snapshot', async () => { - element = ( - await fixture( - html`` - ) - ); - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/voltage-level-editor.test.ts b/packages/plugins/test/unit/editors/substation/voltage-level-editor.test.ts deleted file mode 100644 index 0a6ec1021b..0000000000 --- a/packages/plugins/test/unit/editors/substation/voltage-level-editor.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '../../../../src/editors/substation/voltage-level-editor.js'; -import { VoltageLevelEditor } from '../../../../src/editors/substation/voltage-level-editor.js'; - -describe('voltage-level-editor', () => { - let element: VoltageLevelEditor; - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element = ( - await fixture( - html`` - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - - describe('with readonly property', () => { - beforeEach(async () => { - element.readonly = true; - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with function filter deactivated', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('VoltageLevel')!; - element.showfunctions = true; - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with function filter deactivated and existing LNode children', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('VoltageLevel[name="J1"]')!; - element.showfunctions = true; - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); - - describe('with general-equipment children', () => { - beforeEach(async () => { - doc = await fetch( - '/test/testfiles/editors/substation/generalequipment.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.element = doc.querySelector('VoltageLevel')!; - element.showfunctions = false; - await element.updateComplete; - }); - - it('with showfunctions false looks like the latest snapshot', async () => - await expect(element).shadowDom.to.equalSnapshot()); - - it('with showfunctions true looks like the latest snapshot', async () => { - element.showfunctions = true; - await element.updateComplete; - - await expect(element).shadowDom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/substation/zeroline-pane.test.ts b/packages/plugins/test/unit/editors/substation/zeroline-pane.test.ts deleted file mode 100644 index b84b12a8eb..0000000000 --- a/packages/plugins/test/unit/editors/substation/zeroline-pane.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '../../../../src/editors/substation/zeroline-pane.js'; -import { ZerolinePane } from '../../../../src/editors/substation/zeroline-pane.js'; -import { - attachedIeds, - getAttachedIeds, -} from '../../../../src/editors/substation/foundation.js'; - -describe('zeroline-pane', () => { - let doc: XMLDocument; - - let substation1: Element; - let substation2: Element; - - let voltageLevel1: Element; - let voltageLevel2: Element; - - let bay1: Element; - let bay2: Element; - - let remainingIeds: Set; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/zeroline/iedalloctest.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - substation1 = doc.querySelector('Substation[name="AA1"]')!; - substation2 = doc.querySelector('Substation[name="AA2"]')!; - - voltageLevel1 = doc.querySelector('VoltageLevel[name="E1"]')!; - voltageLevel2 = doc.querySelector('VoltageLevel[name="J1"]')!; - - bay1 = doc.querySelector('Bay[name="Bay1"]')!; - bay2 = doc.querySelector('Bay[name="Bay2"]')!; - - remainingIeds = new Set(Array.from(doc.querySelectorAll('IED'))); - }); - - it('per default looks like the latest snapshot', async () => { - const element: ZerolinePane = await fixture( - html`` - ); - - if (element.showieds.on) await element.showieds.click(); - if (element.showfunctions.on) await element.showfunctions.click(); - - await new Promise(resolve => setTimeout(resolve, 2000)); // await animation - - await expect(element).shadowDom.to.equalSnapshot(); - }).timeout(5000); - - it('showieds looks like the latest snapshot', async () => { - const element: ZerolinePane = await fixture( - html`` - ); - - if (!element.showieds.on) await element.showieds.click(); - if (element.showfunctions.on) await element.showfunctions.click(); - - await new Promise(resolve => setTimeout(resolve, 2000)); // await IEDs are rendered - - await expect(element).shadowDom.to.equalSnapshot(); - }).timeout(5000); - - describe('attachedIeds', () => { - it('returns IEDs that cannot be allocated to any element', async () => { - const ieds = await attachedIeds(doc.documentElement!, remainingIeds); - - expect(ieds.length).to.equal(2); - expect(ieds[0].getAttribute('name')).to.equal('IED6'); - expect(ieds[1].getAttribute('name')).to.equal('IED8'); - }); - describe('return IEDs for Bay elements that', () => { - it('are connected itself or underlaying conduncting equipment', async () => { - const ieds = await attachedIeds(bay1, remainingIeds); - - expect(ieds.length).to.equal(2); - expect(ieds[0].getAttribute('name')).to.equal('IED1'); - expect(ieds[1].getAttribute('name')).to.equal('IED4'); - }); - - it('are not connected to another Bay as well', async () => { - expect((await attachedIeds(bay2, remainingIeds)).length).to.equal(0); - }); - }); - describe('return IEDs for VoltageLevel elements that', () => { - it('are connected itself or underlaying elements', async () => { - const ieds = await attachedIeds(voltageLevel1, remainingIeds); - - expect(ieds.length).to.equal(2); - expect(ieds[0].getAttribute('name')).to.equal('IED2'); - expect(ieds[1].getAttribute('name')).to.equal('IED5'); - }); - - it('are not connected to another Bay ass well', async () => { - expect( - (await attachedIeds(voltageLevel2, remainingIeds)).length - ).to.equal(0); - }); - }); - describe('return IEDs for Substation elements that', () => { - it('are connected itself or underlaying elements', async () => { - const ieds = await attachedIeds(substation1, remainingIeds); - - expect(ieds.length).to.equal(2); - expect(ieds[0].getAttribute('name')).to.equal('IED3'); - expect(ieds[1].getAttribute('name')).to.equal('IED7'); - }); - it('are not connected to another Substation ass well', async () => { - expect( - (await attachedIeds(substation2, remainingIeds)).length - ).to.equal(0); - }); - }); - }); - - it('both the functions return every IED only once', async () => { - const numSub1 = (await attachedIeds(substation1, remainingIeds)).length; - const numSub2 = (await attachedIeds(substation2, remainingIeds)).length; - const numVolt1 = (await attachedIeds(voltageLevel1, remainingIeds)).length; - const numVolt2 = (await attachedIeds(voltageLevel2, remainingIeds)).length; - const numBay1 = (await attachedIeds(bay1, remainingIeds)).length; - const numBay2 = (await attachedIeds(bay2, remainingIeds)).length; - - const numUnRef = (await attachedIeds(doc.documentElement, remainingIeds)) - .length; - - const sumIeds = - numBay1 + numBay2 + numVolt1 + numVolt2 + numSub1 + numSub2 + numUnRef; - - expect(sumIeds).to.equal(doc.querySelectorAll('IED').length); - }); -}).timeout(10000); diff --git a/packages/plugins/test/unit/editors/templates/datype.test.ts b/packages/plugins/test/unit/editors/templates/datype.test.ts deleted file mode 100644 index 7ea7671281..0000000000 --- a/packages/plugins/test/unit/editors/templates/datype.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - identity, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - Replace, - isSimple -} from '@openscd/core/foundation/deprecated/editor.js'; -import { editDaTypeWizard } from '../../../../src/editors/templates/datype-wizards.js'; - -describe('wizards for DAType element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editDaTypeWizard( - identity(doc.querySelector('DAType')), - doc - )!; - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - describe('allows to edit id attribute', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'id'); - }); - - it('as wizard input', () => expect(input).to.exist); - - it('triggers a complex action', () => { - input!.value = 'someTestId'; - primaryAction.click(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('that edits the id attribute of DAType', () => { - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions[0].new.element).to.have.attribute('id', 'someTestId'); - }); - - it('that edits all referenced lnType attribute as well', () => { - const oldId = input?.value; - const numReferences = doc.querySelectorAll( - `DOType > DA[type="${oldId}"], DAType > BDA[type="${oldId}"]` - ).length; - - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions).to.have.lengthOf(numReferences + 1); - - actions.shift(); //the first updates the DAType itself and has no 'id' - for (const action of actions) - expect(action.new.element).to.have.attribute('type', 'someTestId'); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/templates/dotype.test.ts b/packages/plugins/test/unit/editors/templates/dotype.test.ts deleted file mode 100644 index 8dad5e14cb..0000000000 --- a/packages/plugins/test/unit/editors/templates/dotype.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - identity, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - Replace, - isSimple -} from '@openscd/core/foundation/deprecated/editor.js'; -import { dOTypeWizard } from '../../../../src/editors/templates/dotype-wizards.js'; - -describe('wizards for DOType element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = dOTypeWizard( - identity(doc.querySelector('DOType')), - doc - )!; - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - describe('allows to edit id attribute', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'id'); - }); - - it('as wizard input', () => expect(input).to.exist); - - it('triggers a complex action', () => { - input!.value = 'someTestId'; - primaryAction.click(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('that edits the id attribute of DOType', () => { - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions[0].new.element).to.have.attribute('id', 'someTestId'); - }); - - it('that edits all referenced lnType attribute as well', () => { - const oldId = input?.value; - const numReferences = doc.querySelectorAll( - `LNodeType > DO[type="${oldId}"], DOType > SDO[type="${oldId}"]` - ).length; - - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions).to.have.lengthOf(numReferences + 1); - actions.shift(); //the first updates the DOType itself and has no 'id' - for (const action of actions) - expect(action.new.element).to.have.attribute('type', 'someTestId'); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/templates/enumtype.test.ts b/packages/plugins/test/unit/editors/templates/enumtype.test.ts deleted file mode 100644 index 7f183baa1c..0000000000 --- a/packages/plugins/test/unit/editors/templates/enumtype.test.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - identity, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - Replace, - isSimple -} from '@openscd/core/foundation/deprecated/editor.js'; -import { eNumTypeEditWizard } from '../../../../src/editors/templates/enumtype-wizard.js'; - -describe('wizards for EnumType element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = eNumTypeEditWizard( - identity(doc.querySelector('EnumType')), - doc - )!; - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - describe('allows to edit id attribute', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'id'); - }); - - it('as wizard input', () => expect(input).to.exist); - - it('triggers a complex action', () => { - input!.value = 'someTestId'; - primaryAction.click(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('that edits the id attribute of EnumType', () => { - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions[0].new.element).to.have.attribute('id', 'someTestId'); - }); - - it('that edits all referenced lnType attribute as well', () => { - const oldId = input?.value; - const numReferences = doc.querySelectorAll( - `DOType > DA[type="${oldId}"], DAType > BDA[type="${oldId}"]` - ).length; - - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions).to.have.lengthOf(numReferences + 1); - - actions.shift(); //the first updates the EnumType itself and has no 'id' - for (const action of actions) - expect(action.new.element).to.have.attribute('type', 'someTestId'); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/editors/templates/lnodetype-wizard.test.ts b/packages/plugins/test/unit/editors/templates/lnodetype-wizard.test.ts deleted file mode 100644 index 614f091424..0000000000 --- a/packages/plugins/test/unit/editors/templates/lnodetype-wizard.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - identity, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - Replace, - isSimple -} from '@openscd/core/foundation/deprecated/editor.js'; -import { lNodeTypeWizard } from '../../../../src/editors/templates/lnodetype-wizard.js'; -import { regExp, regexString } from '../../../foundation.js'; - -describe('wizards for LNodeType element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = lNodeTypeWizard( - identity(doc.querySelector('LNodeType')), - doc - )!; - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - describe('allows to edit lnClass attribute', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'lnClass'); - }); - - it('as wizard input', () => expect(input).to.exist); - - it('for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.lnClass, 4, 4), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('takes the exception LLN0 into account', async () => { - input!.value = 'LLN0'; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }); - }); - - describe('allows to edit id attribute', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'id'); - }); - - it('as wizard input', () => expect(input).to.exist); - - it('triggers a complex action', () => { - input!.value = 'someTestId'; - primaryAction.click(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('that edits the id attribute of LNodeType', () => { - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions[0].new.element).to.have.attribute('id', 'someTestId'); - }); - - it('that edits all referenced lnType attribute as well', () => { - const oldId = input?.value; - const numReferences = doc.querySelectorAll( - `LN0[lnType="${oldId}"], LN[lnType="${oldId}"]` - ).length; - - input!.value = 'someTestId'; - primaryAction.click(); - - const complexAction = ( - actionEvent.args[0][0].detail.action - ); - const actions = complexAction.actions; - expect(actions).to.have.lengthOf(numReferences + 1); - actions.shift(); //the first updates the LNodeType itself and has no 'id' - for (const action of actions) - expect(action.new.element).to.have.attribute('lnType', 'someTestId'); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/menu/CompareIED.test.ts b/packages/plugins/test/unit/menu/CompareIED.test.ts deleted file mode 100644 index e231d82694..0000000000 --- a/packages/plugins/test/unit/menu/CompareIED.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import CompareIEDPlugin from '../../../src/menu/CompareIED.js'; -import { PlainCompareList } from '@openscd/open-scd/src/plain-compare-list.js'; - -describe('Compare IED Plugin', () => { - if (customElements.get('compare-ied') === undefined) - customElements.define('compare-ied', CompareIEDPlugin); - - let plugin: CompareIEDPlugin; - let doc: XMLDocument; - let template: XMLDocument; - - beforeEach(async () => { - plugin = await fixture(html``); - doc = await fetch('/test/testfiles/menu/compare-ied-changed.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - template = await fetch('/test/testfiles/menu/compare-ied-original.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('show template project selection dialog', () => { - beforeEach(async () => { - plugin.doc = doc; - plugin.run(); - await plugin.requestUpdate(); - }); - - it('after closing the dialog everything set to undefined', async () => { - expect(plugin.templateDoc).to.be.undefined; - expect(plugin.selectedProjectIed).to.be.undefined; - expect(plugin.selectedTemplateIed).to.be.undefined; - - plugin['onClosed'](); - await plugin.requestUpdate(); - - expect(plugin.templateDoc).to.be.undefined; - expect(plugin.selectedProjectIed).to.be.undefined; - expect(plugin.selectedTemplateIed).to.be.undefined; - }); - - it('looks like its latest snapshot', async () => { - await expect(plugin.dialog).to.equalSnapshot(); - }); - }); - - describe('show ied selection lists dialog', () => { - beforeEach(async () => { - plugin.doc = doc; - plugin.templateDoc = template; - plugin.run(); - await plugin.requestUpdate(); - }); - - it('expect the correct number of IEDs from project', () => { - expect(plugin.ieds).to.have.length(5); - }); - - it('expect the correct number of IEDs from template project', () => { - expect(plugin.templateIeds).to.have.length(4); - }); - - it('after closing the dialog everything set to undefined', async () => { - expect(plugin.templateDoc).to.not.be.undefined; - expect(plugin.selectedProjectIed).to.be.undefined; - expect(plugin.selectedTemplateIed).to.be.undefined; - - plugin['onClosed'](); - await plugin.requestUpdate(); - - // expect(plugin.templateDoc).to.be.undefined; - expect(plugin.selectedProjectIed).to.be.undefined; - expect(plugin.selectedTemplateIed).to.be.undefined; - }); - - it('looks like its latest snapshot', async () => { - await expect(plugin.dialog).to.equalSnapshot(); - }); - }); - - describe('show compare dialog with no differences', () => { - beforeEach(async () => { - plugin.doc = doc; - plugin.templateDoc = template; - plugin.selectedProjectIed = - doc.querySelector('IED[name="FieldC_QA1_QB1_QB2_QC9"]') ?? undefined; - plugin.selectedTemplateIed = - template.querySelector('IED[name="FieldC_QA1_QB1_QB2_QC9"]') ?? - undefined; - plugin.run(); - await plugin.requestUpdate(); - }); - - it('looks like its latest snapshot', async () => { - await expect(plugin.dialog).to.equalSnapshot(); - }); - }); - - describe('show compare dialog with differences', () => { - beforeEach(async () => { - plugin.doc = doc; - plugin.templateDoc = template; - plugin.selectedProjectIed = - doc.querySelector('IED[name="FieldA_QA1_QB1_QB2_QC9"]') ?? undefined; - plugin.selectedTemplateIed = - template.querySelector('IED[name="FieldA_QA1_QB1_QB2_QC9"]') ?? - undefined; - plugin.run(); - await plugin.requestUpdate(); - }); - - it('after closing the dialog everything set to undefined', async () => { - expect(plugin.templateDoc).to.not.be.undefined; - expect(plugin.selectedProjectIed).to.not.be.undefined; - expect(plugin.selectedTemplateIed).to.not.be.undefined; - - plugin['onClosed'](); - await plugin.requestUpdate(); - - expect(plugin.selectedProjectIed).to.be.undefined; - expect(plugin.selectedTemplateIed).to.be.undefined; - }); - - }); - -}); diff --git a/packages/plugins/test/unit/menu/SclHistory.test.ts b/packages/plugins/test/unit/menu/SclHistory.test.ts deleted file mode 100644 index 449609f0a1..0000000000 --- a/packages/plugins/test/unit/menu/SclHistory.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import SclHistoryPlugin from '../../../src/menu/SclHistory.js'; - -describe('testing sclHistory dialog', () => { - if (customElements.get('scl-history') === undefined) - customElements.define('scl-history', SclHistoryPlugin); - let plugin: SclHistoryPlugin; - let doc: XMLDocument; - - describe('with a document loaded containing SCL history items', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/history.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - plugin = await fixture(html` `); - plugin.run(); - await plugin.requestUpdate(); - }); - - it('looks like its latest snapshot', async () => { - await expect(plugin.historyLog).to.equalSnapshot(); - }); - - it('has 7 items in the history list', () => { - expect(plugin.sclHistory.length).to.be.equal(7); - }); - - describe('testing createMessage function', () => { - it('creates a message with two valid strings', () => { - expect(plugin['createMessage']('string who', 'string why')).to.be.equal( - 'string who : string why' - ); - }); - - it('creates a message with one valid string or returns undefined', () => { - expect(plugin['createMessage']('string who', null)).to.be.equal( - 'string who' - ); - expect(plugin['createMessage'](null, 'string why')).to.be.equal( - 'string why' - ); - expect(plugin['createMessage'](null, null)).to.be.undefined; - }); - }); - }); - - describe('with no document', () => { - beforeEach(async () => { - plugin = await fixture(html` `); - plugin.run(); - await plugin.requestUpdate(); - }); - it('looks like its latest snapshot', async () => { - await expect(plugin.historyLog).to.equalSnapshot(); - }); - it('has no items in the history list', () => { - expect(plugin.sclHistory).to.be.empty; - }); - }); - - describe('with a document without SCL history items', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/no-history.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - plugin = await fixture(html` `); - plugin.run(); - await plugin.requestUpdate(); - }); - it('looks like its latest snapshot', async () => { - await expect(plugin.historyLog).to.equalSnapshot(); - }); - it('has no items in the history list', () => { - expect(plugin.sclHistory).to.be.empty; - }); - }); -}); diff --git a/packages/plugins/test/unit/menu/SubscriberInfo.test.ts b/packages/plugins/test/unit/menu/SubscriberInfo.test.ts deleted file mode 100644 index f6108c4342..0000000000 --- a/packages/plugins/test/unit/menu/SubscriberInfo.test.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { createMissingIEDNameSubscriberInfo } from '../../../src/menu/SubscriberInfo.js'; -import { isCreate } from '@openscd/core/foundation/deprecated/editor.js'; -import { - SimpleAction, - Create, -} from '@openscd/core/foundation/deprecated/editor.js'; - -describe('menu plugin adding subscriber info', () => { - describe('for Edition2 and higher files', () => { - let doc: Document; - let actions: SimpleAction[]; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/subscriberinfo2007.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - actions = createMissingIEDNameSubscriberInfo(doc); - }); - - it('does create one action per necessary IEDName creation', () => { - expect(actions.length).to.equal(4); - }); - - it('creates correct IEDName element referencing LN0 element', () => { - expect(actions[0]).to.satisfy(isCreate); - expect( - ((actions[0]).new.element).getAttribute('apRef') - ).to.equal('P1'); - expect( - ((actions[0]).new.element).getAttribute('ldInst') - ).to.equal('CBSW'); - expect( - ((actions[0]).new.element).getAttribute('prefix') - ).to.equal(''); - expect( - ((actions[0]).new.element).getAttribute('lnClass') - ).to.equal('LLN0'); - expect( - ((actions[0]).new.element).getAttribute('lnInst') - ).to.equal(null); - expect((actions[0]).new.element.textContent).to.equal('IED2'); - }); - - it('creates correct IEDName element referencing LN element', () => { - expect(actions[1]).to.satisfy(isCreate); - expect( - ((actions[1]).new.element).getAttribute('apRef') - ).to.equal('P1'); - expect( - ((actions[1]).new.element).getAttribute('ldInst') - ).to.equal('CBSW'); - expect( - ((actions[1]).new.element).getAttribute('prefix') - ).to.equal(''); - expect( - ((actions[1]).new.element).getAttribute('lnClass') - ).to.equal('XSWI'); - expect( - ((actions[1]).new.element).getAttribute('lnInst') - ).to.equal('1'); - expect((actions[1]).new.element.textContent).to.equal('IED2'); - }); - - it('creates correct IEDName element referencing LN element', () => { - expect(actions[2]).to.satisfy(isCreate); - expect( - ((actions[2]).new.element).getAttribute('apRef') - ).to.equal('P1'); - expect( - ((actions[2]).new.element).getAttribute('ldInst') - ).to.equal('Disconnectors'); - expect( - ((actions[2]).new.element).getAttribute('prefix') - ).to.equal('DC'); - expect( - ((actions[2]).new.element).getAttribute('lnClass') - ).to.equal('CSWI'); - expect( - ((actions[2]).new.element).getAttribute('lnInst') - ).to.equal('1'); - expect((actions[2]).new.element.textContent).to.equal('IED1'); - }); - - it('creates correct IEDName element referencing LN element', () => { - expect(actions[3]).to.satisfy(isCreate); - expect( - ((actions[3]).new.element).getAttribute('apRef') - ).to.equal('P1'); - expect( - ((actions[3]).new.element).getAttribute('ldInst') - ).to.equal('Disconnectors'); - expect( - ((actions[3]).new.element).getAttribute('prefix') - ).to.equal(''); - expect( - ((actions[3]).new.element).getAttribute('lnClass') - ).to.equal('CSWI'); - expect( - ((actions[3]).new.element).getAttribute('lnInst') - ).to.equal('2'); - expect((actions[3]).new.element.textContent).to.equal('IED1'); - }); - }); - - describe('for Edition1 files', () => { - let doc: Document; - let actions: SimpleAction[]; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/subscriberinfo2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - actions = createMissingIEDNameSubscriberInfo(doc); - }); - - it('does create one action per necessary IEDName creation', () => { - expect(actions.length).to.equal(2); - }); - - it('creates correct IEDName element', () => { - expect(actions[0]).to.satisfy(isCreate); - expect((actions[0]).new.element.textContent).to.equal('IED1'); - }); - - it('creates correct IEDName element', () => { - expect(actions[1]).to.satisfy(isCreate); - expect((actions[1]).new.element.textContent).to.equal('IED1'); - }); - - it('does not add Edition2 attributes into the IEDName element', () => { - actions.forEach(action => { - expect(((action).new.element).getAttribute('apRef')).to - .be.null; - expect(((action).new.element).getAttribute('ldInst')) - .to.be.null; - expect(((action).new.element).getAttribute('prefix')) - .to.be.null; - expect(((action).new.element).getAttribute('lnClass')) - .to.be.null; - expect(((action).new.element).getAttribute('lnInst')) - .to.be.null; - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/menu/UpdateDescriptionSEL.test.ts b/packages/plugins/test/unit/menu/UpdateDescriptionSEL.test.ts deleted file mode 100644 index 5b3a3b4985..0000000000 --- a/packages/plugins/test/unit/menu/UpdateDescriptionSEL.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/test/mock-open-scd.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -import { - ComplexAction, - isSimple, - isReplace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import UpdateDescriptionSel from '../../../src/menu/UpdateDescriptionSEL.js'; - -describe('Update method for desc attributes in SEL IEDs', () => { - if (customElements.get('update-description-sel') === undefined) - customElements.define('update-description-sel', UpdateDescriptionSel); - - let parent: MockOpenSCD; - let element: UpdateDescriptionSel; - - let wizardAction: SinonSpy; - let editorAction: SinonSpy; - - let signalList: string; - - beforeEach(async () => { - parent = await fixture(html` - - `); - - element = ( - parent.querySelector('update-description-sel')! - ); - await element.requestUpdate(); - - editorAction = spy(); - window.addEventListener('editor-action', editorAction); - wizardAction = spy(); - window.addEventListener('wizard', wizardAction); - }); - - it('allows to select signal list only as csv file', async () => { - expect(element.pluginFileUI).to.have.property('accept', '.csv'); - expect(element.pluginFileUI).to.have.property('type', 'file'); - }); - - it('allows to select signal list as csv file', async () => { - await element.run(); - }); - - describe('working on SCL files without manufacturer SEL', () => { - beforeEach(async () => { - const doc = await fetch('test/testfiles/validators/zeroissues.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element.doc = doc; - - signalList = await fetch( - 'test/testfiles/updatedesc/testSignalListSemicolon.csv' - ).then(response => response.text()); - - element.processSignalList(signalList); - await parent.requestUpdate(); - }); - - it('cannot find any desc fields to update', async () => { - expect(wizardAction).to.have.been.calledOnce; - expect(parent.wizardUI.dialog?.querySelector('mwc-checked-list-item')).to - .be.null; - }); - }); - - describe('working on SCL files containing manufacturer SEL', () => { - beforeEach(async () => { - const doc = await fetch('test/testfiles/updatedesc/updatedescSEL.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element.doc = doc; - }); - - describe('using a semicolon separated file', () => { - beforeEach(async () => { - signalList = await fetch( - 'test/testfiles/updatedesc/testSignalListSemicolon.csv' - ).then(response => response.text()); - - element.processSignalList(signalList); - await parent.requestUpdate(); - }); - - it('creates filtered list with all proposed desc attribute updates', async () => { - await expect(parent.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - it('allows to update selected desc attributes updates', async () => { - parent.wizardUI?.dialog - ?.querySelector('mwc-button[slot="primaryAction"]')! - .click(); - - await parent.updateComplete; - expect(editorAction).to.have.been.calledOnce; - expect(editorAction.args[0][0].detail.action).to.not.satisfy(isSimple); - const complexAction = ( - editorAction.args[0][0].detail.action - ); - expect(complexAction.actions.length).to.equal(7); - for (const action of complexAction.actions) - expect(action).to.satisfy(isReplace); - }); - }); - - describe('using a comma separated (CSV) file', () => { - beforeEach(async () => { - signalList = await fetch( - 'test/testfiles/updatedesc/testSignalListComma.csv' - ).then(response => response.text()); - - element.processSignalList(signalList); - await parent.requestUpdate(); - }); - - it('creates filtered list with all proposed desc attribute updates', async () => { - await expect(parent.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - it('allows to update selected desc attributes updates', async () => { - parent.wizardUI?.dialog - ?.querySelector('mwc-button[slot="primaryAction"]')! - .click(); - - await parent.updateComplete; - expect(editorAction).to.have.been.calledOnce; - expect(editorAction.args[0][0].detail.action).to.not.satisfy(isSimple); - const complexAction = ( - editorAction.args[0][0].detail.action - ); - expect(complexAction.actions.length).to.equal(7); - for (const action of complexAction.actions) - expect(action).to.satisfy(isReplace); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/menu/UpdateDescritionABB.test.ts b/packages/plugins/test/unit/menu/UpdateDescritionABB.test.ts deleted file mode 100644 index 7bf0de4a6e..0000000000 --- a/packages/plugins/test/unit/menu/UpdateDescritionABB.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import sinon, { SinonSpy } from 'sinon'; - -import '@openscd/open-scd/test/mock-open-scd.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -import { - ComplexAction, - isSimple, - isReplace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import UpdateDescriptionAbb from '../../../src/menu/UpdateDescriptionABB.js'; - -describe('Update method for desc attributes in ABB IEDs', () => { - if (customElements.get('update-description-abb') === undefined) - customElements.define('update-description-abb', UpdateDescriptionAbb); - - let parent: MockOpenSCD; - let element: UpdateDescriptionAbb; - - let editorAction: SinonSpy; - - beforeEach(async () => { - parent = await fixture(html` - - `); - - element = parent.getActivePlugin(); - - editorAction = sinon.spy(); - window.addEventListener('editor-action', editorAction); - }); - - describe('working on SCL files without manufacturer ABB', () => { - beforeEach(async () => { - const doc = await fetch('/test/testfiles/validators/zeroissues.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element.doc = doc; - element.run(); - await parent.requestUpdate(); - }); - - it('creates an empty wizard indicating not found desc updates', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - }); - - describe('working on SCL files containing manufacturer ABB', () => { - beforeEach(async () => { - const doc = await fetch('/test/testfiles/updatedesc/updatedescABB.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - element.doc = doc; - element.run(); - await parent.requestUpdate(); - }); - - it('creates a wizard with all valid desc update possibilities', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - it('creates wizard that on save triggers a complex action containing selected desc updates', async () => { - parent.wizardUI?.dialog - ?.querySelector('mwc-button[slot="primaryAction"]')! - .click(); - await parent.updateComplete; - expect(editorAction).to.have.been.calledOnce; - expect(editorAction.args[0][0].detail.action).to.not.satisfy(isSimple); - const complexAction = ( - editorAction.args[0][0].detail.action - ); - expect(complexAction.actions.length).to.equal(2); - for (const action of complexAction.actions) - expect(action).to.satisfy(isReplace); - }); - }); -}); diff --git a/packages/plugins/test/unit/menu/VirtualTemplateIED.test.ts b/packages/plugins/test/unit/menu/VirtualTemplateIED.test.ts deleted file mode 100644 index 6b9b290292..0000000000 --- a/packages/plugins/test/unit/menu/VirtualTemplateIED.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import { Create, isCreate } from '@openscd/core/foundation/deprecated/editor.js'; -import VirtualTemplateIED from '../../../src/menu/VirtualTemplateIED.js'; -import { CheckListItem } from '@material/mwc-list/mwc-check-list-item'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; - -describe('Plugin that creates with some user input a virtual template IED - SPECIFICATION', () => { - if (customElements.get('virtual-template-i-e-d') === undefined) - customElements.define('virtual-template-i-e-d', VirtualTemplateIED); - - let doc: XMLDocument; - let element: VirtualTemplateIED; - - let manufacturer: WizardTextField; - let apName: WizardTextField; - - let primaryAction: HTMLElement; - let checkItems: CheckListItem[]; - - let editorAction: SinonSpy; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/virtualied/specificfromfunctions.ssd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element = await fixture(html` - - `); - - editorAction = spy(); - window.addEventListener('editor-action', editorAction); - - element.run(); - await element.requestUpdate(); - - checkItems = Array.from( - element.dialog.querySelectorAll('mwc-check-list-item') ?? [] - ); - manufacturer = element.dialog.querySelector( - 'wizard-textfield[label="manufacturer"]' - )!; - apName = element.dialog.querySelector( - 'wizard-textfield[label="AccessPoint name"]' - )!; - - primaryAction = ( - element.dialog.querySelector('mwc-button[slot="primaryAction"]') - ); - }); - - it('looks like the latest snapshot', async () => - await expect(element.dialog).dom.to.equalSnapshot()); - - it('shows all LNode that is not class LLN0 as check list items', () => - expect(checkItems.length).to.equal( - doc.querySelectorAll('LNode[iedName="None"]:not([lnClass="LLN0"])').length - )); - - it('does not trigger any actions with missing input fields', () => { - primaryAction.click(); - - expect(editorAction).to.not.have.been.called; - }); - - it('does not trigger any actions with missing input fields', () => { - manufacturer.value = 'SomeCompanyName'; - apName.value = 'P1'; - - primaryAction.click(); - - expect(editorAction).to.not.have.been.called; - }); - - it('does trigger an create actions if at least one LNode is selected', async () => { - manufacturer.value = 'SomeCompanyName'; - apName.value = 'P1'; - - checkItems[1].selected = true; - - await element.requestUpdate(); - - primaryAction.click(); - - expect(editorAction).to.have.been.calledOnce; - }); - - it('allows to add more than one SPECIFICATION type IED to the document', async () => { - manufacturer.value = 'SomeCompanyName'; - apName.value = 'P1'; - - checkItems[1].selected = true; - - await element.requestUpdate(); - - primaryAction.click(); - - const action = editorAction.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - - const createAction = action; - expect(createAction.checkValidity).to.exist; - expect(createAction.checkValidity!()).to.be.true; - }); - - it('enables primary action button only with required information', async () => { - expect(primaryAction).to.have.attribute('disabled'); - - manufacturer.value = 'SomeCompanyName'; - apName.value = 'P1'; - await element.requestUpdate(); - - expect(primaryAction).to.have.attribute('disabled'); - - checkItems[1].selected = true; - await element.requestUpdate(); - - expect(primaryAction).to.not.have.attribute('disabled'); - }); - - it('IEDs data model show selected logical nodes and its structure', async () => { - manufacturer.value = 'SomeCompanyName'; - apName.value = 'P1'; - - checkItems[1].selected = true; - checkItems[10].selected = true; - checkItems[15].selected = true; - - await element.requestUpdate(); - - primaryAction.click(); - - const action = editorAction.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - - const createAction = action; - await expect(createAction.new.element).dom.to.equalSnapshot(); - }); -}); diff --git a/packages/plugins/test/unit/menu/__snapshots__/CompareIED.test.snap.js b/packages/plugins/test/unit/menu/__snapshots__/CompareIED.test.snap.js deleted file mode 100644 index 9820784237..0000000000 --- a/packages/plugins/test/unit/menu/__snapshots__/CompareIED.test.snap.js +++ /dev/null @@ -1,194 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Compare IED Plugin show template project selection dialog looks like its latest snapshot"] = -` -
    - - - -
    - - -
    -`; -/* end snapshot Compare IED Plugin show template project selection dialog looks like its latest snapshot */ - -snapshots["Compare IED Plugin show ied selection lists dialog looks like its latest snapshot"] = -` -
    -
    -
    - [compare-ied.projectIedTitle] -
    -
    - - - - FieldA_QA1_QB1_QB2_QC9 - - - - - FieldB_QA1_QB1_QB2_QC9 - - - - - FieldC_QA1_QB1_QB2_QC9 - - - - - FieldC_QA1_QB1_QB2_QCX - - - - - IED1 - - - -
    -
    -
    -
    - [compare-ied.templateIedTitle] -
    -
    - - - - FieldA_QA1_QB1_QB2_QC9 - - - - - FieldB_QA1_QB1_QB2_QC9 - - - - - FieldC_QA1_QB1_QB2_QC9 - - - - - SPECIFICATION - - - -
    -
    -
    - - - - -
    -`; -/* end snapshot Compare IED Plugin show ied selection lists dialog looks like its latest snapshot */ - -snapshots["Compare IED Plugin show compare dialog with no differences looks like its latest snapshot"] = -` - - - - - - - -`; -/* end snapshot Compare IED Plugin show compare dialog with no differences looks like its latest snapshot */ - diff --git a/packages/plugins/test/unit/menu/__snapshots__/SclHistory.test.snap.js b/packages/plugins/test/unit/menu/__snapshots__/SclHistory.test.snap.js deleted file mode 100644 index 49b376671b..0000000000 --- a/packages/plugins/test/unit/menu/__snapshots__/SclHistory.test.snap.js +++ /dev/null @@ -1,212 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["testing sclHistory dialog with a document loaded containing SCL history items looks like its latest snapshot"] = -` - - - - - - - - - Test User 1 : Small correction in substation - - - - - - - - - SCD updated, Nice history test 5 - - - - - - - - - - - SCD updated, Nice history test 4 - - - Small correction in substation - - - - - - - - invalid - - SCD updated, Nice history test 3 - - - Test User 1 : Small correction in substation - - - - - - - - - SCD updated, Nice history test 2 - - - Test User 1 - - - - - - - - 2021-09-14T10:52:28Z - - SCD created, Nice history test 1 - - - Test User 1 - - - - - - - - 2021-09-14T10:51:38Z - - SCD created from CIM File(s): some-cim-file.xml - - - Test User 1 - - - - - - [close] - - -`; -/* end snapshot testing sclHistory dialog with a document loaded containing SCL history items looks like its latest snapshot */ - -snapshots["testing sclHistory dialog with no document looks like its latest snapshot"] = -` - - - - [history.noEntries] - - - - - [close] - - -`; -/* end snapshot testing sclHistory dialog with no document looks like its latest snapshot */ - -snapshots["testing sclHistory dialog with a document without SCL history items looks like its latest snapshot"] = -` - - - - [history.noEntries] - - - - - [close] - - -`; -/* end snapshot testing sclHistory dialog with a document without SCL history items looks like its latest snapshot */ - diff --git a/packages/plugins/test/unit/menu/__snapshots__/UpdateDescriptionSEL.test.snap.js b/packages/plugins/test/unit/menu/__snapshots__/UpdateDescriptionSEL.test.snap.js deleted file mode 100644 index 6db5470cc7..0000000000 --- a/packages/plugins/test/unit/menu/__snapshots__/UpdateDescriptionSEL.test.snap.js +++ /dev/null @@ -1,285 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Update method for desc attributes in SEL IEDs working on SCL files containing manufacturer SEL using a semicolon separated file creates filtered list with all proposed desc attribute updates"] = -` -
    - - - - CB_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind01>stVal - - - - - CB_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind02>stVal - - - - - BB1_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind03>stVal - - - - - BB1_DS_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind04>stVal - - - - - BB2_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind05>stVal - - - - - BB2_DS_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind06>stVal - - - - - LINE_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind07>stVal - - - -
    - - - - -
    -`; -/* end snapshot Update method for desc attributes in SEL IEDs working on SCL files containing manufacturer SEL using a semicolon separated file creates filtered list with all proposed desc attribute updates */ - -snapshots["Update method for desc attributes in SEL IEDs working on SCL files containing manufacturer SEL using a comma separated (CSV) file creates filtered list with all proposed desc attribute updates"] = -` -
    - - - - CB_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind01>stVal - - - - - CB_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind02>stVal - - - - - BB1_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind03>stVal - - - - - BB1_DS_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind04>stVal - - - - - BB2_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind05>stVal - - - - - BB2_DS_OPEN - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind06>stVal - - - - - LINE_DS_CLOSED - - - DAI | IED2>>CBSW>IN1 GGIO 14>Ind07>stVal - - - -
    - - - - -
    -`; -/* end snapshot Update method for desc attributes in SEL IEDs working on SCL files containing manufacturer SEL using a comma separated (CSV) file creates filtered list with all proposed desc attribute updates */ - diff --git a/packages/plugins/test/unit/menu/__snapshots__/UpdateDescritionABB.test.snap.js b/packages/plugins/test/unit/menu/__snapshots__/UpdateDescritionABB.test.snap.js deleted file mode 100644 index 665efe7e9d..0000000000 --- a/packages/plugins/test/unit/menu/__snapshots__/UpdateDescritionABB.test.snap.js +++ /dev/null @@ -1,93 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Update method for desc attributes in ABB IEDs working on SCL files without manufacturer ABB creates an empty wizard indicating not found desc updates"] = -` -
    - - -
    - - - - -
    -`; -/* end snapshot Update method for desc attributes in ABB IEDs working on SCL files without manufacturer ABB creates an empty wizard indicating not found desc updates */ - -snapshots["Update method for desc attributes in ABB IEDs working on SCL files containing manufacturer ABB creates a wizard with all valid desc update possibilities"] = -` -
    - - - - GOOSERCV_BIN.3.I1 - - - ExtRef | IED1>>Disconnectors>DC CSWI 1>01-0C-CD-01-00-01,0001,5,GOOSERCV_BIN.3.I1,400,0,GOOSERCV_BIN,Dynamic[0] - - - - - some desc-GOOSERCV_BIN.3.I2 - - - ExtRef | IED1>>Disconnectors>DC CSWI 1>01-0C-CD-01-00-01,0001,5,GOOSERCV_BIN.3.I2,400,0,GOOSERCV_BIN,Dynamic[0] - - - -
    - - - - -
    -`; -/* end snapshot Update method for desc attributes in ABB IEDs working on SCL files containing manufacturer ABB creates a wizard with all valid desc update possibilities */ - diff --git a/packages/plugins/test/unit/menu/__snapshots__/VirtualTemplateIED.test.snap.js b/packages/plugins/test/unit/menu/__snapshots__/VirtualTemplateIED.test.snap.js deleted file mode 100644 index b753457b04..0000000000 --- a/packages/plugins/test/unit/menu/__snapshots__/VirtualTemplateIED.test.snap.js +++ /dev/null @@ -1,631 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Plugin that creates with some user input a virtual template IED - SPECIFICATION looks like the latest snapshot"] = -` -
    - - - - - - - - - - E1_Q01_QC9_Earth_Switch - - - AA1>E1>Q01>QC9>Earth_Switch - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - CSWI 1 - - - CILO 1 - - - XSWI 1 - -
  • -
  • - - - Q01_QB1_Disconnector - - - AA1>E1>Q01>QB1>Disconnector - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - CSWI 1 - - - XSWI 1 - - - CILO 1 - -
  • -
  • - - - Circuit_Breaker - - - AA1>E1>Q01>QA1>Circuit_Breaker - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - CSWI 1 - - - CILO 1 - - - XCBR 1 - -
  • -
  • - - - Timed_Overcurrent - - - AA1>E1>Q01>Timed_Overcurrent - - - - - OpenSCD_LLN01 - - - - ID_ PTOC 2 - - - IDD_ PTOC 1 - -
  • -
  • - - - Distance_Protection - - - AA1>E1>Q01>Distance_Protection - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - Zone4 PDIS 1 - - - Zon3 PDIS 1 - - - Zone2 PDIS 1 - - - Zone1 PDIS 1 - -
  • -
  • - - - Q02_QB1_Disconnector - - - AA1>E1>Q02>QB1>Disconnector - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - CSWI 1 - - - XSWI 1 - - - CILO 1 - -
  • -
  • - - - J1_Q01_QC9_Earth_Switch - - - AA1>J1>Q01>QC9>Earth_Switch - - - - - OpenSCD_LLN0 - - - OpenSCD_LLN01 - - - - CSWI 1 - - - CILO 1 - - - XSWI 1 - -
  • -
  • -
    -
    - - - - -
    -`; -/* end snapshot Plugin that creates with some user input a virtual template IED - SPECIFICATION looks like the latest snapshot */ - -snapshots["Plugin that creates with some user input a virtual template IED - SPECIFICATION IEDs data model show selected logical nodes and its structure"] = -` - - - - - - - - - - - - - - - - - - - - - - - - - -`; -/* end snapshot Plugin that creates with some user input a virtual template IED - SPECIFICATION IEDs data model show selected logical nodes and its structure */ - diff --git a/packages/plugins/test/unit/menu/updatesubstation.test.ts b/packages/plugins/test/unit/menu/updatesubstation.test.ts deleted file mode 100644 index 052a3cc39b..0000000000 --- a/packages/plugins/test/unit/menu/updatesubstation.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { isValidReference } from '../../../src/menu/UpdateSubstation.js'; -import { identity } from '@openscd/open-scd/src/foundation.js'; - -describe('isValidReference', () => { - let ours: XMLDocument; - beforeEach(async () => { - ours = await fetch('/test/testfiles/updatesubstation-ours.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('returns true for lNodeIdentity pointing to logical node in the IED', () => { - const lNode = ours.querySelector( - 'LNode[iedName="IED1"][ldInst="Disconnectors"][prefix="DC"][lnClass="XSWI"][lnInst="1"]' - ); - expect(isValidReference(ours, identity(lNode))).to.be.true; - }); - it('checks reference for client side logical nodes', () => { - const lNode = ours.querySelector( - 'LNode[iedName="IED1"][prefix="DC3"][lnClass="XSWI"][lnInst="2"]' - ); - expect(isValidReference(ours, identity(lNode))).to.be.true; - }); - it('returns false for NaN identities', () => { - expect(isValidReference(ours, NaN)).to.be.false; - }); - it('returns false for incorrect lNodeIdentities', () => { - const lNodeMissingIedNAme = ours.querySelector( - 'LNode[iedName="IED1"][prefix="DC"][lnClass="XSWI"][lnInst="2"]' - ); - lNodeMissingIedNAme?.removeAttribute('iedName'); - expect(isValidReference(ours, identity(lNodeMissingIedNAme))).to.be.false; - const lNodeMissingLnClass = ours.querySelector( - 'LNode[iedName="IED1"][prefix="DC"][lnClass="XSWI"][lnInst="2"]' - ); - lNodeMissingLnClass?.removeAttribute('iedName'); - expect(isValidReference(ours, identity(lNodeMissingLnClass))).to.be.false; - }); - it('returns false when reference does not match with logical node', () => { - const lNode = ours.querySelector( - 'LNode[iedName="IED1"][ldInst="Disconnectors"][prefix="DC"][lnClass="XSWI"][lnInst="1"]' - ); - lNode?.setAttribute('lnClass', 'LPHD'); - expect(isValidReference(ours, identity(lNode))).to.be.false; - }); -}); diff --git a/packages/plugins/test/unit/menu/virtualtemplateied/__snapshots__/foundation.test.snap.js b/packages/plugins/test/unit/menu/virtualtemplateied/__snapshots__/foundation.test.snap.js deleted file mode 100644 index a3ab415204..0000000000 --- a/packages/plugins/test/unit/menu/virtualtemplateied/__snapshots__/foundation.test.snap.js +++ /dev/null @@ -1,48 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["foundation for virtual IED creation getSpecificationIED function looks like the latest snapshot"] = -` - - - - - - - - - - - - - - - - - - - -`; -/* end snapshot foundation for virtual IED creation getSpecificationIED function looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/menu/virtualtemplateied/foundation.test.ts b/packages/plugins/test/unit/menu/virtualtemplateied/foundation.test.ts deleted file mode 100644 index 7afdc25d1c..0000000000 --- a/packages/plugins/test/unit/menu/virtualtemplateied/foundation.test.ts +++ /dev/null @@ -1,266 +0,0 @@ -import { expect } from '@open-wc/testing'; -import { identity } from '@openscd/open-scd/src/foundation.js'; - -import { - getFunctionNamingPrefix, - getNonLeafParent, - getSpecificationIED, - getUniqueFunctionName, - isLeafFunction, - VirtualIEDDescription, -} from '../../../../src/menu/virtualtemplateied/foundation.js'; - -describe('foundation for virtual IED creation', () => { - describe('function checking for leaf function type elements', () => { - let randomElement: Element; - let leafSubFunction: Element; - let nonLeafSubFunction: Element; - let leafEqSubFunction: Element; - let nonLeafEqSubFunction: Element; - - beforeEach(() => { - randomElement = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - leafSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - nonLeafSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - leafEqSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - nonLeafEqSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns false for input null', () => - expect(isLeafFunction(null)).to.be.false); - - it('returns false for Function element', () => - expect(isLeafFunction(randomElement)).to.be.false); - - it('returns true for leaf SubFcuntion element', () => - expect(isLeafFunction(leafSubFunction)).to.be.true); - - it('returns true for non-leaf SubFuction element', () => - expect(isLeafFunction(nonLeafSubFunction)).to.be.false); - - it('returns true for leaf EqSubFunction element', () => - expect(isLeafFunction(leafEqSubFunction)).to.be.true); - - it('returns true for non-leaf SubFunction element', () => - expect(isLeafFunction(nonLeafEqSubFunction)).to.be.false); - }); - - describe('getNonLeafParent function', () => { - let invalidParantTag: Element; - let directParent: Element; - let directParentsLNode: Element | null; - let leafParent: Element; - let leafParentsLNode: Element | null; - - beforeEach(() => { - invalidParantTag = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - directParent = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - directParentsLNode = directParent.querySelector('LNode'); - - leafParent = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - leafParentsLNode = leafParent.querySelector('LNode'); - }); - - it('return null for null inputs', () => - expect(getNonLeafParent(null)).to.be.null); - - it('returns null for invalid closest parent tag', () => - expect(getNonLeafParent(invalidParantTag)).to.be.null); - - it('returns null for invalid parent tag', () => - expect(getNonLeafParent(directParentsLNode)).to.equal(directParent)); - - it('returns null for invalid parent tag', () => - expect(getNonLeafParent(leafParentsLNode)).to.equal(leafParent)); - }); - - describe('getFunctionNamingPrefix function', () => { - let lNodeWithPrefix: Element; - let lNodeWithOutPrefix: Element; - let leafSubFunction: Element; - let leafSubFunctionsLNode: Element; - let nonLeafSubFunction: Element; - let nonLeafSubFunctionsLNode: Element; - - beforeEach(() => { - lNodeWithPrefix = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - lNodeWithOutPrefix = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - - leafSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - leafSubFunctionsLNode = leafSubFunction.querySelector('LNode')!; - - nonLeafSubFunction = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - nonLeafSubFunctionsLNode = nonLeafSubFunction.querySelector('LNode')!; - }); - - it('return prefix attribute if present in LNode', () => - expect(getFunctionNamingPrefix(lNodeWithPrefix)).to.equal( - lNodeWithPrefix.getAttribute('prefix') - )); - - it('return empty string if no valid prefix exist', () => - expect(getFunctionNamingPrefix(lNodeWithOutPrefix)).to.equal('')); - - it('returns leaf SubFunction name for missing prefix attribute', () => - expect(getFunctionNamingPrefix(leafSubFunctionsLNode)).to.be.equal( - 'leafFunction' - )); - - it('returns empty string if no valid string exist', () => - expect(getFunctionNamingPrefix(nonLeafSubFunctionsLNode)).to.be.equal( - '' - )); - }); - - describe('getUniqueFunctionName function', () => { - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/virtualied/specificfromfunctions.ssd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return unique name for function type element', () => - expect( - getUniqueFunctionName( - doc.querySelector('EqFunction[name="Disconnector"]')! - ) - ).to.equal('Q01_QB1_Disconnector')); - - it('return unique name for another function type element', () => - expect( - getUniqueFunctionName( - doc.querySelector('EqFunction[name="Earth_Switch"]')! - ) - ).to.equal('E1_Q01_QC9_Earth_Switch')); - - it('return function type element name if already unique in project', () => - expect( - getUniqueFunctionName( - doc.querySelector('Function[name="Distance_Protection"]')! - ) - ).to.equal('Distance_Protection')); - - it('return identity string in case input element is not function type element', () => - expect(getUniqueFunctionName(doc.querySelector('Bay')!)).to.equal( - identity(doc.querySelector('Bay')) - )); - }); - - describe('getUniqueFunctionName function', () => { - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/virtualied/specificfromfunctions.ssd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return unique name for function type element', () => - expect( - getUniqueFunctionName( - doc.querySelector('EqFunction[name="Disconnector"]')! - ) - ).to.equal('Q01_QB1_Disconnector')); - - it('return unique name for another function type element', () => - expect( - getUniqueFunctionName( - doc.querySelector('EqFunction[name="Earth_Switch"]')! - ) - ).to.equal('E1_Q01_QC9_Earth_Switch')); - - it('return function type element name if already unique in project', () => - expect( - getUniqueFunctionName( - doc.querySelector('Function[name="Distance_Protection"]')! - ) - ).to.equal('Distance_Protection')); - - it('return identity string in case input element is not function type element', () => - expect(getUniqueFunctionName(doc.querySelector('Bay')!)).to.equal( - identity(doc.querySelector('Bay')) - )); - }); - - describe('getSpecificationIED function', () => { - let doc: XMLDocument; - let virtualIED: VirtualIEDDescription; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/virtualied/specificfromfunctions.ssd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - virtualIED = { - manufacturer: 'some manufactorer', - desc: null, - apName: 'P1', - lDevices: [ - { - validLdInst: 'someProtection', - anyLNs: [ - { lnClass: 'LLN0', inst: '', prefix: null, lnType: 'someLLN0' }, - { lnClass: 'PTOC', inst: '1', prefix: 'IDD', lnType: 'somePTOC' }, - ], - }, - { - validLdInst: 'someControl', - anyLNs: [ - { lnClass: 'LLN0', inst: '', prefix: null, lnType: 'someLLN0' }, - { lnClass: 'CSWI', inst: '1', prefix: '', lnType: 'someCSWI' }, - ], - }, - ], - }; - }); - - it('looks like the latest snapshot', async () => - await expect( - getSpecificationIED(doc, virtualIED) - ).dom.to.equalSnapshot()); - }); -}); diff --git a/packages/plugins/test/unit/validators/ValidateTemplates.test.ts b/packages/plugins/test/unit/validators/ValidateTemplates.test.ts deleted file mode 100644 index 3154a8655d..0000000000 --- a/packages/plugins/test/unit/validators/ValidateTemplates.test.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/test/mock-open-scd.js'; -import { MockOpenSCD } from '@openscd/open-scd/test/mock-open-scd.js'; - -import ValidateTemplates from '../../../src/validators/ValidateTemplates.js'; - -describe('ValidateTemplates', () => { - if (customElements.get('validate-templates') === undefined) - customElements.define('validate-templates', ValidateTemplates); - - let logEvent: SinonSpy; - let issueEvent: SinonSpy; - - beforeEach(async () => { - logEvent = spy(); - issueEvent = spy(); - - window.addEventListener('log', logEvent); - window.addEventListener('issue', issueEvent); - }); - - describe('dispatch', () => { - let element: ValidateTemplates; - - beforeEach(async () => { - const doc = await fetch('/test/testfiles/validators/zeroissues.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const parent: MockOpenSCD = await fixture(html` - - `); - - element = parent.getActivePlugin(); - - await parent.updateComplete; - }); - - it('triggers as newIssuesEvent for detail not containing kind', () => { - const detail = { - title: 'title', - message: 'message', - }; - element.dispatch(detail); - expect(issueEvent).to.have.been.called; - expect(logEvent).to.not.have.been.called; - expect(issueEvent.args[0][0].type).to.equal('issue'); - expect(issueEvent.args[0][0].detail.validatorId).to.equal( - '/src/validators/ValidateTemplates.js' - ); - expect(issueEvent.args[0][0].detail.message).to.equal('message'); - expect(issueEvent.args[0][0].detail.title).to.equal('title'); - }); - - it('triggers as newLogEvent for detail containing kind info', () => { - const detail = { - kind: 'info', - title: 'title', - message: 'message', - }; - element.dispatch(detail); - expect(logEvent).to.have.been.called; - expect(issueEvent).to.not.have.been.called; - expect(logEvent.args[0][0].type).to.equal('log'); - expect(logEvent.args[0][0].detail.kind).to.equal('info'); - expect(logEvent.args[0][0].detail.message).to.equal('message'); - expect(logEvent.args[0][0].detail.title).to.equal('title'); - }); - - it('triggers as newLogEvent for detail containing kind warning', () => { - const detail = { - kind: 'warning', - title: 'title', - message: 'message', - }; - element.dispatch(detail); - expect(logEvent).to.have.been.called; - expect(issueEvent).to.not.have.been.called; - expect(logEvent.args[0][0].type).to.equal('log'); - expect(logEvent.args[0][0].detail.kind).to.equal('warning'); - }); - - it('triggers as newLogEvent for detail containing kind error', () => { - const detail = { - kind: 'error', - title: 'title', - message: 'message', - }; - element.dispatch(detail); - expect(logEvent).to.have.been.called; - expect(issueEvent).to.not.have.been.called; - expect(logEvent.args[0][0].type).to.equal('log'); - expect(logEvent.args[0][0].detail.kind).to.equal('error'); - }); - }); - - describe('validate', () => { - let element: ValidateTemplates; - beforeEach(async () => { - const doc = await fetch('/test/testfiles/validators/zeroissues.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const parent: MockOpenSCD = await fixture(html` - - `); - - element = parent.getActivePlugin(); - - await parent.updateComplete; - }); - - it('pushes only diag.zeroissues issue to diagnostics when no issues found', async () => { - await element.validate(); - expect(issueEvent).to.have.been.calledOnce; - expect(issueEvent.args[0][0].detail.title).to.contain( - 'No errors found in the project' - ); - }); - - it('pushes only diag.missingnsd issue to diagnostics pane for SCL version < 2007B3', async () => { - element.doc.querySelector('SCL')?.setAttribute('version', '2003'); - await element.validate(); - expect(issueEvent).to.have.been.calledOnce; - expect(issueEvent.args[0][0].detail.title).to.contain( - 'Cannot validate DataTypeTemplates. The version of the project must be higher than or equal to 2007B3' - ); - }); - - it('pushes only diag.missingnsd issue to diagnostics pane for SCL not having version information', async () => { - element.doc.querySelector('SCL')?.removeAttribute('version'); - element.doc.querySelector('SCL')?.removeAttribute('revision'); - await element.validate(); - expect(issueEvent).to.have.been.calledOnce; - expect(issueEvent.args[0][0].detail.title).to.contain( - 'Cannot validate DataTypeTemplates. The version of the project must be higher than or equal to 2007B3' - ); - }); - - it('does not trigger anything for SCL missing DataTypeTemplates', async () => { - const data = element.doc.querySelector('DataTypeTemplates')!; - element.doc.querySelector('SCL')?.removeChild(data); - await element.validate(); - expect(issueEvent).to.not.have.been.calledOnce; - }); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/dabda.test.ts b/packages/plugins/test/unit/validators/templates/dabda.test.ts deleted file mode 100644 index c67385371c..0000000000 --- a/packages/plugins/test/unit/validators/templates/dabda.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { dAValidator } from '../../../../src/validators/templates/dabda.js'; - -describe('da or bda validator', () => { - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/validators/doandsdotestfile.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return Issues when DA type attribute is missing for Struct type', async () => { - const element = doc.querySelector('DOType[id="missingType1"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return empty array for correct DA type attribute - Struct type', async () => { - const element = doc.querySelector('DOType[id="existingType1"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(0); - }); - - it('return Issues when DA type attribute is missing for Enum type', async () => { - const element = doc.querySelector('DOType[id="missingType2"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return empty array for correct DA type attribute - Enum type', async () => { - const element = doc.querySelector('DOType[id="existingType2"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(0); - }); - - it('return Issues when DA type reference is missing - Struct type', async () => { - const element = doc.querySelector('DOType[id="invalidReference1"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); - - it('return Issues when DA type reference is missing - Enum type', async () => { - const element = doc.querySelector('DOType[id="invalidReference2"] > DA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); - - it('return Issues when BDA type attribute is missing - Struct type', async () => { - const element = doc.querySelector('DAType[id="missingType1"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return empty array for correct BDA type attribute - Struct type', async () => { - const element = doc.querySelector('DAType[id="existingType1"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(0); - }); - - it('return Issues when BDA type attribute is missing for Enum type', async () => { - const element = doc.querySelector('DAType[id="missingType2"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return empty array for correct BDA type attribute - Enum type', async () => { - const element = doc.querySelector('DAType[id="existingType2"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(0); - }); - - it('return Issues when BDA type reference is missing - Struct type', async () => { - const element = doc.querySelector('DAType[id="invalidReference1"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); - - it('return Issues when BDA type reference is missing - Enum type', async () => { - const element = doc.querySelector('DAType[id="invalidReference2"] > BDA')!; - const errors = await dAValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/datype.test.ts b/packages/plugins/test/unit/validators/templates/datype.test.ts deleted file mode 100644 index 19a50641b0..0000000000 --- a/packages/plugins/test/unit/validators/templates/datype.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { dATypeValidator } from '../../../../src/validators/templates/datype.js'; - -describe('datype validator', () => { - let doc: XMLDocument; - beforeEach(async () => { - doc = await fetch('/test/testfiles/validators/datatypetemplateerrors.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return empty array if element is not DAType', async () => { - const element = doc.querySelector('DOType')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); - it('returns empty array if DAType includes all mandatory BDAs', async () => { - const element = doc.querySelector('DAType[id="Dummy.RangeConfig"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); - it('return Issues for missing mandatory BDA e.g scaledOffset', async () => { - const element = doc.querySelector('DAType[id="Dummy.ScaledValueConfig"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns Issues for missing DA within Oper structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.Operfalse"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns empty array for correct Oper structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.Oper"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns Issue array for missing DA within SBOw structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.SBOwfalse"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns empty array for correct SBOw structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.SBOw"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns Issue array for missing DA within Cancel structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.Cancelfalse"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns empty array for correct Cancel structure', async () => { - const element = doc.querySelector('DAType[id="Dummy.Cancel"]')!; - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns empty array id less DAType', async () => { - const element = doc.querySelector('DAType[id="Dummy.Cancelfalse"]')!; - element.removeAttribute('id'); - const errors = await dATypeValidator(element); - expect(errors.length).to.equal(0); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/doorsdo.test.ts b/packages/plugins/test/unit/validators/templates/doorsdo.test.ts deleted file mode 100644 index 18495ae309..0000000000 --- a/packages/plugins/test/unit/validators/templates/doorsdo.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { dOValidator } from '../../../../src/validators/templates/dosdo.js'; - -describe('do or sdo validator', () => { - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/validators/doandsdotestfile.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return Issues when DO type attribute is missing', async () => { - const typelessDo = doc.querySelector('LNodeType[id="typelessDo"] > DO')!; - const errors = await dOValidator(typelessDo); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return Issues when DO type reference is missing', async () => { - const referencelessDo = doc.querySelector('LNodeType[id="relessDo"] > DO')!; - const errors = await dOValidator(referencelessDo); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); - - it('return Issues when SDO type attribute is missing', async () => { - const typelessSDo = doc.querySelector('LNodeType[id="typelessSDo"] > SDO')!; - const errors = await dOValidator(typelessSDo); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return Issues when SDO type reference is missing', async () => { - const reflessSDo = doc.querySelector('LNodeType[id="relessSDo"] > SDO')!; - const errors = await dOValidator(reflessSDo); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingReference'); - }); - - it('return empty array for valid DO or SDO', async () => { - const correctDo = doc.querySelector('LNodeType[id="correctDo"] > DO')!; - const errors = await dOValidator(correctDo); - expect(errors.length).to.equal(0); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/dotype.test.ts b/packages/plugins/test/unit/validators/templates/dotype.test.ts deleted file mode 100644 index 3edf03435e..0000000000 --- a/packages/plugins/test/unit/validators/templates/dotype.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { dOTypeValidator } from '../../../../src/validators/templates/dotype.js'; - -describe('dotype validator', () => { - let doc: XMLDocument; - beforeEach(async () => { - doc = await fetch('/test/testfiles/validators/datatypetemplateerrors.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return empty array if element is not DOType', async () => { - const element = doc.querySelector('LNodeType')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns empty array if DOType includes all mandatory DAs', async () => { - const element = doc.querySelector('DOType[id="Dummy.LPHD1.Sim"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('return Issues for missing mandatory DA e.g stVal', async () => { - const element = doc.querySelector('DOType[id="Dummy.LLN0.Health"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('return Issues for missing mandatory DA e.g another stVal', async () => { - const element = doc.querySelector('DOType[id="Dummy.XCBR1.Pos"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('return Issues for missing mandatory DA e.g ctlModel', async () => { - const element = doc.querySelector('DOType[id="Dummy.CSWI.Pos1"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('return Issues for missing cdc attribute within DOType', async () => { - const element = doc.querySelector('DOType[id="Dummy.MissingCDC"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('return Issues if CDC definition does not follow NSD ', async () => { - const element = doc.querySelector('DOType[id="Dummy.XCBR1.badNamPlt"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('does not validate CDC to NSD with missing id', async () => { - const element = doc.querySelector('DOType[id="Dummy.XCBR1.badNamPlt"]')!; - element.removeAttribute('id'); - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns Issues from child validation', async () => { - const element = doc.querySelector('DOType[id="Dummy.badWYE"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns empty array for non-controllable data objects', async () => { - const element = doc.querySelector('DOType[id="Dummy.LPHD1.PhyNam"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('returns Issues for missing SBOw', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC1"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('returns Issues for missing SBO', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC2"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('returns Issues for missing Oper', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC3"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('returns Issues for missing Cancel', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC3"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('mandatoryChild'); - }); - - it('does not indicate false positive for status-only DOs', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC4"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('does not indicate false positive for empty ctlModel', async () => { - const element = doc.querySelector('DOType[id="Dummy.XCBR1.Pos1"]')!; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); - - it('does not indicate false positive for wrong ctlModel', async () => { - const element = doc.querySelector('DOType[id="Dummy.SPC4"]')!; - const val = element.querySelector('Val')!; - val.innerHTML = 'invalidCtlModel'; - const errors = await dOTypeValidator(element); - expect(errors.length).to.equal(0); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/foundation.test.ts b/packages/plugins/test/unit/validators/templates/foundation.test.ts deleted file mode 100644 index 36510b28a3..0000000000 --- a/packages/plugins/test/unit/validators/templates/foundation.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { - tagValidator, - validateChildren, -} from '../../../../src/validators/templates/foundation.js'; - -describe('validator foundation', () => { - describe('tagValidator', () => { - it('tagValidator returns undefined with missing tagName', () => { - expect(tagValidator['noTag']).to.be.undefined; - }); - }); - describe('validateChildren', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - it('does not throw Issues for unknown childTags', async () => { - const issues = await validateChildren(element); - expect(issues.length).to.equal(0); - }); - }); -}); diff --git a/packages/plugins/test/unit/validators/templates/lnodetype.test.ts b/packages/plugins/test/unit/validators/templates/lnodetype.test.ts deleted file mode 100644 index 42a8ccd961..0000000000 --- a/packages/plugins/test/unit/validators/templates/lnodetype.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { lNodeTypeValidator } from '../../../../src/validators/templates/lnodetype.js'; - -describe('lnodetype validator', () => { - let doc: XMLDocument; - beforeEach(async () => { - doc = await fetch('/test/testfiles/validators/datatypetemplateerrors.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('return Issue for missing mandatory DO e.g Beh', async () => { - const element = doc.querySelector('LNodeType[id="Dummy.CILO"]')!; - const errors = await lNodeTypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('return Issues for missing mandatory DO e.g Pos', async () => { - const element = doc.querySelector('LNodeType[id="Dummy.CSWI"]')!; - const errors = await lNodeTypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns Issues if child element is invalid', async () => { - const element = doc.querySelector('LNodeType[id="Dummy.invalidChild"]')!; - const errors = await lNodeTypeValidator(element); - expect(errors.length).to.equal(1); - }); - - it('returns Issues if lnClass attribute is missing', async () => { - const element = doc.querySelector('LNodeType[id="Dummy.CILO"]')!; - element.removeAttribute('lnClass'); - const errors = await lNodeTypeValidator(element); - expect(errors.length).to.equal(1); - expect(errors[0].title).to.contain('missingAttribute'); - }); - - it('returns empty array if LNodeType includes all mandatory DOs', async () => { - const element = doc.querySelector('LNodeType[id="Dummy.GGIO1"]')!; - const errors = await lNodeTypeValidator(element); - expect(errors.length).to.equal(0); - }); -}); diff --git a/packages/plugins/test/unit/wizards/__snapshots__/abstractda.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/abstractda.test.snap.js deleted file mode 100644 index d76371c828..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/abstractda.test.snap.js +++ /dev/null @@ -1,525 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["abstractda wizards renderWizard looks like the latest snapshot"] = -` -
    - - > - - - - - - BOOLEAN - - - INT8 - - - INT16 - - - INT24 - - - INT32 - - - INT64 - - - INT128 - - - INT8U - - - INT16U - - - INT24U - - - INT32U - - - FLOAT32 - - - FLOAT64 - - - Enum - - - Dbpos - - - Tcmd - - - Quality - - - Timestamp - - - VisString32 - - - VisString64 - - - VisString65 - - - VisString129 - - - VisString255 - - - Octet64 - - - Unicode255 - - - Struct - - - EntryTime - - - Check - - - ObjRef - - - Currency - - - PhyComAddr - - - TrgOps - - - OptFlds - - - SvOptFlds - - - LogOptFlds - - - EntryID - - - Octet6 - - - Octet16 - - - - - AnalogueValue_i - - - ScaledValueConfig - - - Dummy_origin - - - Dummy.LLN0.Mod.SBOw - - - Dummy.LLN0.Mod.Cancel - - - Dummy.LPHD1.Sim.SBOw - - - Dummy.LPHD1.Sim.Cancel - - - Dummy_ctlModel - - - Dummy_Beh - - - Dummy_Health - - - Dummy_orCategory - - - - - - - Spec - - - Conf - - - RO - - - Set - - - - - - - - -
    - - -
    -`; -/* end snapshot abstractda wizards renderWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/address.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/address.test.snap.js deleted file mode 100644 index 4f6747779d..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/address.test.snap.js +++ /dev/null @@ -1,54 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["address renderGseSmvAddress looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - -
    - - -
    -`; -/* end snapshot address renderGseSmvAddress looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/clientln.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/clientln.test.snap.js deleted file mode 100644 index 41315aad8c..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/clientln.test.snap.js +++ /dev/null @@ -1,403 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["clientln wizards createClientLnWizard looks like the latest snapshot"] = -` -
    -
    - - - - ReportCb - - - IED2>>CBSW> XSWI 2 - - - 4/5 - - - - - ReportCb - - - IED1>>Disconnectors> XSWI 2 - - - 2/2 - - - - - ReportEmpty - - - IED2>>CBSW> XSWI 1 - - - 0 - - - - - - - DC CILO 1 - - - IED1>P1 - - -
  • -
  • - - - XCBR 1 - - - IED1>>CircuitBreaker_CB1 - - - - - CSWI 1 - - - IED1>>CircuitBreaker_CB1 - - - - - CB XCBR 2 - - - IED1>>CircuitBreaker_CB1 - - - - - CB CSWI 2 - - - IED1>>CircuitBreaker_CB1 - - - - - DC XSWI 1 - - - IED1>>Disconnectors - - - - - DC CSWI 1 - - - IED1>>Disconnectors - - - - - DC CILO 1 - - - IED1>>Disconnectors - - - - - XSWI 3 - - - IED1>>Disconnectors - - - - - CSWI 3 - - - IED1>>Disconnectors - - - - - CILO 3 - - - IED1>>Disconnectors - - - - - XSWI 2 - - - IED1>>Disconnectors - - - - - CSWI 2 - - - IED1>>Disconnectors - - - - - LLN0 - - - IED1>>CircuitBreaker_CB1 - - - - - LLN0 - - - IED1>>Disconnectors - - -
    -
    -
    - - - - -
    -`; -/* end snapshot clientln wizards createClientLnWizard looks like the latest snapshot */ - -snapshots["clientln wizards selectClientLnWizard looks like the latest snapshot"] = -` -
    - - - - DCCILO1 - - - - - - - XCBR1 - - - - - - - LLN0 - - - - - -
    - - - - -
    -`; -/* end snapshot clientln wizards selectClientLnWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/commmap.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/commmap.test.snap.js deleted file mode 100644 index 4a7f632a4c..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/commmap.test.snap.js +++ /dev/null @@ -1,187 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["communication mapping wizard looks like the latest snapshot"] = -` -
    - - - - IED1 - - trending_flat - - IED3 - - - Disconnectors> XSWI 2>ReportCb - - - 2 - - - - - - - IED2 - - trending_flat - - IED1 - - - CBSW> XSWI 2>ReportCb - - - 3 - - - - - - - IED2 - - trending_flat - - IED3 - - - CBSW> XSWI 2>ReportCb - - - 1 - - - - - - - IED3 - - trending_flat - - IED1 - - - MU01>MSVCB01 - - - 14 - - - - - - - IED2 - - trending_flat - - IED1 - - - CBSW>GCB - - - 2 - - - - - - - IED1 - - trending_flat - - IED2 - - - CircuitBreaker_CB1>GCB - - - 4 - - - - - -
    - - -
    -`; -/* end snapshot communication mapping wizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/connectedap-c.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/connectedap-c.test.snap.js deleted file mode 100644 index 3a884af34a..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/connectedap-c.test.snap.js +++ /dev/null @@ -1,224 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["create wizard for ConnectedAP element looks like the latest snapshot"] = -` -
    - - - - GOOSE_Publisher>AP2 - - - - - GOOSE_Publisher>AP3 - - - - - GOOSE_Publisher>AP4 - - - - - GOOSE_Publisher2>AP1 - - - - - GOOSE_Publisher2>AP2 - - - - - GOOSE_Publisher2>AP3 - - - - - GOOSE_Publisher2>AP4 - - - - - GOOSE_Subscriber>AP1 - - - - - GOOSE_Subscriber>AP2 - - - - - SMV_Publisher>AP1 - - - - - SMV_Publisher>AP3 - - - - - SMV_Publisher>AP4 - - - - - SMV_Publisher2>AP1 - - - - - SMV_Publisher2>AP2 - - - - - SMV_Publisher2>AP3 - - - - - GOOSE_Publisher>AP1 - - - - - SMV_Publisher>AP2 - - - -
    - - - - -
    -`; -/* end snapshot create wizard for ConnectedAP element looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/connectedap-pattern.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/connectedap-pattern.test.snap.js deleted file mode 100644 index 0066d025cc..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/connectedap-pattern.test.snap.js +++ /dev/null @@ -1,560 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 1 projects looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 1 projects looks like the latest snapshot */ - -snapshots["Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 2 projects looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 2 projects looks like the latest snapshot */ - -snapshots["Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 2.1 projects looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Edit wizard for SCL element ConnectedAP include an edit wizard that for Edition 2.1 projects looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/connectivitynode.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/connectivitynode.test.snap.js deleted file mode 100644 index bf676e40b3..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/connectivitynode.test.snap.js +++ /dev/null @@ -1,40 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element ConnectivityNode looks like the latest snapshot"] = -` -
    - - - - -
    - - -
    -`; -/* end snapshot Wizards for SCL element ConnectivityNode looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/controlwithiedname.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/controlwithiedname.test.snap.js deleted file mode 100644 index 1c0c2bbb78..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/controlwithiedname.test.snap.js +++ /dev/null @@ -1,255 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["selectExtRefWizard looks like the latest snapshot"] = -` -
    - - - - I01ATCTR1>Amp.instMag.i - - - MU01 - - - - - - - I01ATCTR1>Amp.q - - - MU01 - - - - - - - I01BTCTR2>Amp.instMag.i - - - MU01 - - - - - - - I01BTCTR2>Amp.q - - - MU01 - - - - - - - I01CTCTR3>Amp.instMag.i - - - MU01 - - - - - - - I01CTCTR3>Amp.q - - - MU01 - - - - - - - I01NTCTR4>Amp.instMag.i - - - MU01 - - - - - - - I01NTCTR4>Amp.q - - - MU01 - - - - - - - U01ATVTR1>Vol.instMag.i - - - MU01 - - - - - - - U01ATVTR1>Vol.q - - - MU01 - - - - - - - U01BTVTR2>Vol.instMag.i - - - MU01 - - - - - - - U01BTVTR2>Vol.q - - - MU01 - - - - - - - U01CTVTR3>Vol.instMag.i - - - MU01 - - - - - - - U01CTVTR3>Vol.q - - - MU01 - - - - - -
    - - - - -
    -`; -/* end snapshot selectExtRefWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/dai.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/dai.test.snap.js deleted file mode 100644 index 3b59d81648..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/dai.test.snap.js +++ /dev/null @@ -1,129 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element DAI create DAI with existing Val Element looks like the latest snapshot"] = -` -
    - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element DAI create DAI with existing Val Element looks like the latest snapshot */ - -snapshots["Wizards for SCL element DAI create DAI without Val Element looks like the latest snapshot"] = -` -
    - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element DAI create DAI without Val Element looks like the latest snapshot */ - -snapshots["Wizards for SCL element DAI edit existing DAI with Val Element having on value looks like the latest snapshot"] = -` -
    - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element DAI edit existing DAI with Val Element having on value looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/dataset.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/dataset.test.snap.js deleted file mode 100644 index a8b0e5e21c..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/dataset.test.snap.js +++ /dev/null @@ -1,100 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["dataset wizards include a dataset edit wizard looks like the latest snapshot"] = -` - -
    - - - - - - - CBSW/ XSWI 2.Pos stVal (ST) - - - CBSW/ XSWI 2.Pos q (ST) - - - CBSW/ XSWI 2.OpSlc.dsd sasd.ads.asd (ST) - - -
    - - - - -
    -`; -/* end snapshot dataset wizards include a dataset edit wizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/eqfunction.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/eqfunction.test.snap.js deleted file mode 100644 index a04bb5e131..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/eqfunction.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL EqFunction element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL EqFunction element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL EqFunction element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL EqFunction element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/eqsubfunction.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/eqsubfunction.test.snap.js deleted file mode 100644 index a7bb0364db..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/eqsubfunction.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL EqSubFunction element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL EqSubFunction element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL EqSubFunction element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL EqSubFunction element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/fcda.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/fcda.test.snap.js deleted file mode 100644 index 8b3ba85421..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/fcda.test.snap.js +++ /dev/null @@ -1,32 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["create wizard for FCDA element with a valid SCL file looks like the last snapshot"] = -` -
    - - -
    - - - - -
    -`; -/* end snapshot create wizard for FCDA element with a valid SCL file looks like the last snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/function.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/function.test.snap.js deleted file mode 100644 index 626bb08024..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/function.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL Function element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Function element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL Function element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Function element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/generalequipment.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/generalequipment.test.snap.js deleted file mode 100644 index ca80d370d6..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/generalequipment.test.snap.js +++ /dev/null @@ -1,114 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL GeneralEquipment element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL GeneralEquipment element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL GeneralEquipment element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL GeneralEquipment element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/gse.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/gse.test.snap.js deleted file mode 100644 index 5aa0da1125..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/gse.test.snap.js +++ /dev/null @@ -1,75 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["gse wizards editGseWizard looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot gse wizards editGseWizard looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/gsecontrol.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/gsecontrol.test.snap.js deleted file mode 100644 index 888e5ccfab..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/gsecontrol.test.snap.js +++ /dev/null @@ -1,644 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["gsecontrol wizards selectGseControlWizard looks like the latest snapshot"] = -` -
    - - - - GCB - - - IED1>>CircuitBreaker_CB1>GCB - - - - - GCB2 - - - IED1>>CircuitBreaker_CB1>GCB2 - - - - - GCB - - - IED2>>CBSW>GCB - - - -
    - - - - -
    -`; -/* end snapshot gsecontrol wizards selectGseControlWizard looks like the latest snapshot */ - -snapshots["gsecontrol wizards renderGseAttribute looks like the latest snapshot"] = -` -
    - - - - - - - GOOSE - - - GSSE - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - -
    -`; -/* end snapshot gsecontrol wizards renderGseAttribute looks like the latest snapshot */ - -snapshots["gsecontrol wizards editGseControlWizard looks like the latest snapshot"] = -` - -
    - - - - - - - GOOSE - - - GSSE - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - - - -
    -`; -/* end snapshot gsecontrol wizards editGseControlWizard looks like the latest snapshot */ - -snapshots["gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the first page looks like the latest snapshot"] = -` -
    - - - - - - - GOOSE - - - GSSE - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - - - -
    -`; -/* end snapshot gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the first page looks like the latest snapshot */ - -snapshots["gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the second page looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - -
    - - - - - - -
    -`; -/* end snapshot gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the second page looks like the latest snapshot */ - -snapshots["gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the third page looks like the latest snapshot"] = -` -
    - - -
    - - - - - - -
    -`; -/* end snapshot gsecontrol wizards define an create wizard that with existing ConnectedAP element in the Communication section the third page looks like the latest snapshot */ - -snapshots["gsecontrol wizards define an create wizard that with missing ConnectedAP element in the Communication section the second page having a warning message "] = -` -
    -

    - [gse.missingaccp] -

    -
    - - - - - - -
    -`; -/* end snapshot gsecontrol wizards define an create wizard that with missing ConnectedAP element in the Communication section the second page having a warning message */ - -snapshots["gsecontrol wizards define a wizard to select the control block reference looks like the latest snapshot"] = -` -
    - - -
    - - - - -
    -`; -/* end snapshot gsecontrol wizards define a wizard to select the control block reference looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/ied.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/ied.test.snap.js deleted file mode 100644 index fd95e37b4e..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/ied.test.snap.js +++ /dev/null @@ -1,257 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element IED edit IED looks like the latest snapshot"] = -` - -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element IED edit IED looks like the latest snapshot */ - -snapshots["Wizards for SCL element IED remove IED looks like the latest snapshot"] = -` -
    -
    -

    - [ied.wizard.title.references] -

    - - - - Association - - - IED2>P1> - - - - - ClientLN - - - IED2>>CBSW> XSWI 1>ReportCb>IED1 P1 CircuitBreaker_CB1/ XCBR 1 - - - - - ClientLN - - - IED2>>CBSW> XSWI 2>ReportCb>IED1 P1 CircuitBreaker_CB1/ XCBR 1 - - - - - ConnectedAP - - - IED1 P1 - - - - - ExtRef - - - IED2>>CBSW> XSWI 1>IED1 Disconnectors/DC XSWI 1 Pos stVal - - - - - ExtRef - - - IED2>>CBSW> XSWI 1>IED1 Disconnectors/DC XSWI 1 Pos q - - - - - ExtRef - - - IED2>>CircuitBreaker_CB1> CSWI 1>IED1 CircuitBreaker_CB1/ XCBR 1 Pos stVal - - - - - ExtRef - - - IED2>>CircuitBreaker_CB1> CSWI 1>IED1 CircuitBreaker_CB1/ XCBR 1 Pos q - - - - - KDC - - - IED1>IED1 P1 - - - -
    -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element IED remove IED looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/ldevice.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/ldevice.test.snap.js deleted file mode 100644 index 8739657908..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/ldevice.test.snap.js +++ /dev/null @@ -1,52 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element LDevice Allowing/Disallowing ldName editing looks like the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element LDevice Allowing/Disallowing ldName editing looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/line.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/line.test.snap.js deleted file mode 100644 index aa35749841..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/line.test.snap.js +++ /dev/null @@ -1,137 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL Line element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Line element define an edit wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL Line element define a create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Line element define a create wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/lnode.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/lnode.test.snap.js deleted file mode 100644 index 663fb537c8..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/lnode.test.snap.js +++ /dev/null @@ -1,912 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for LNode element contain a LNode instantiate wizard that with existing LLN0 and LPHD instances looks like the latest snapshot"] = -` - -
    - - - - LLN0 - - - [lnode.wizard.uniquewarning] - - - - - LPHD - - - [lnode.wizard.uniquewarning] - - - - - XCBR - - - #Dummy.XCBR1 - - - - - CSWI - - - #Dummy.CSWI - - - - - CILO - - - #Dummy.CILO - - - - - CSWI - - - #Dummy.CSWIwithoutCtlModel - - - - - XSWI - - - #Dummy.XSWI1 - - - - - GGIO - - - #Dummy.GGIO1 - - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a LNode instantiate wizard that with existing LLN0 and LPHD instances looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a LNode instantiate wizard that with existing LLN0 but missing LPHD instances looks like the latest snapshot"] = -` - -
    - - - - LLN0 - - - [lnode.wizard.uniquewarning] - - - - - LPHD - - - #Dummy.LPHD1 - - - - - XCBR - - - #Dummy.XCBR1 - - - - - CSWI - - - #Dummy.CSWI - - - - - CILO - - - #Dummy.CILO - - - - - CSWI - - - #Dummy.CSWIwithoutCtlModel - - - - - XSWI - - - #Dummy.XSWI1 - - - - - GGIO - - - #Dummy.GGIO1 - - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a LNode instantiate wizard that with existing LLN0 but missing LPHD instances looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a LNode instantiate wizard that with missing LLN0 and LPHD instances looks like the latest snapshot"] = -` - -
    - - - - LLN0 - - - #Dummy.LLN0 - - - - - LPHD - - - #Dummy.LPHD1 - - - - - XCBR - - - #Dummy.XCBR1 - - - - - CSWI - - - #Dummy.CSWI - - - - - CILO - - - #Dummy.CILO - - - - - CSWI - - - #Dummy.CSWIwithoutCtlModel - - - - - XSWI - - - #Dummy.XSWI1 - - - - - GGIO - - - #Dummy.GGIO1 - - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a LNode instantiate wizard that with missing LLN0 and LPHD instances looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a LNode reference create wizard that with references to existing logical nodes looks like the latest snapshot"] = -` -
    - - - - XSWI2 - - - IED2 | - CBSW - - - - - XCBR1 - - - IED2 | - CBSW - - - - - XSWI1 - - - IED2 | - CBSW - - - - - GGIO1 - - - IED2 | - CBSW - - - - - LLN0 - - - IED2 | - CircuitBreaker_CB1 - - - - - XCBR1 - - - IED2 | - CircuitBreaker_CB1 - - - - - CSWI1 - - - IED2 | - CircuitBreaker_CB1 - - - - - LLN0 - - account_tree - - /AA1/E1/COUPLING_BAY - - - IED2 | - CBSW - - - - - LPHD1 - - account_tree - - /AA1/E1/COUPLING_BAY - - - IED2 | - CBSW - - - - - XSWI3 - - account_tree - - /AA1/E1/COUPLING_BAY - - - IED2 | - CBSW - - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a LNode reference create wizard that with references to existing logical nodes looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a LNode reference create wizard that with missing references to existing logical nodes looks like the latest snapshot"] = -` - -
    - - - IED1 - - - IED2 - - - IED3 - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a LNode reference create wizard that with missing references to existing logical nodes looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a edit wizard that for a type reference looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a edit wizard that for a type reference looks like the latest snapshot */ - -snapshots["Wizards for LNode element contain a edit wizard that for a IED reference looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for LNode element contain a edit wizard that for a IED reference looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/optfields.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/optfields.test.snap.js deleted file mode 100644 index 2ae3ab88ca..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/optfields.test.snap.js +++ /dev/null @@ -1,78 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL OptFields element define an edit wizard that looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL OptFields element define an edit wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/powertransformer.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/powertransformer.test.snap.js deleted file mode 100644 index c55c94373f..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/powertransformer.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element Power Transformer edit existing Power Transformer looks like the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element Power Transformer edit existing Power Transformer looks like the latest snapshot */ - -snapshots["Wizards for SCL element Power Transformer add new Power Transformer looks like the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element Power Transformer add new Power Transformer looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/process.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/process.test.snap.js deleted file mode 100644 index 7141393744..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/process.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL Process element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Process element define an edit wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL Process element define a create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Process element define a create wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/reportcontrol.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/reportcontrol.test.snap.js deleted file mode 100644 index 8de981c6bb..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/reportcontrol.test.snap.js +++ /dev/null @@ -1,865 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL ReportControl element define an edit wizard that for complete ReportControl element looks like the latest snapshot"] = -` - -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an edit wizard that for complete ReportControl element looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define an edit wizard that for ReportControl with missing child elements and referenced DataSet looks like the latest snapshot"] = -` - -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an edit wizard that for ReportControl with missing child elements and referenced DataSet looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define a select wizard that with existing ReportControl element looks like the latest snapshot"] = -` -
    - - - - ReportCb - - - IED2>>CBSW>ReportCb - - - - - ReportCb2 - - - IED2>>CBSW> XSWI 1>ReportCb2 - - - - - ReportCb3 - - - IED2>>CBSW> XSWI 2>ReportCb3 - - - - - ReportCb - - - IED3>>CBSW>ReportCb - - - - - ReportCb2 - - - IED3>>CBSW> XSWI 1>ReportCb2 - - - - - ReportCb - - - IED6>>CBSW>ReportCb - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define a select wizard that with existing ReportControl element looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define a select wizard that with invalid parent looks like the latest snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define a select wizard that with invalid parent looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define an create wizard that the first page looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an create wizard that the first page looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define an create wizard that the second page looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an create wizard that the second page looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define an create wizard that the third page looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - - - - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an create wizard that the third page looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define an create wizard that the forth page looks like the latest snapshot"] = -` -
    - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define an create wizard that the forth page looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define a wizard to select the control block reference looks like the latest snapshot"] = -` -
    - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define a wizard to select the control block reference looks like the latest snapshot */ - -snapshots["Wizards for SCL ReportControl element define copy to other IED selector looks like the latest snapshot"] = -` -
    - - - - IED2 - - - [controlblock.hints.source] - - - - - IED3 - - - [controlblock.hints.exist] - - - - - IED4 - - - [controlblock.hints.noMatchingData] - - - - - IED5 - - - [controlBlock.hints.valid] - - - - - IED6 - - - [controlblock.hints.exist] - - - - - IED7 - - - [controlblock.hints.exist] - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL ReportControl element define copy to other IED selector looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/sampledvaluecontrol.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/sampledvaluecontrol.test.snap.js deleted file mode 100644 index 7f011008a8..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/sampledvaluecontrol.test.snap.js +++ /dev/null @@ -1,808 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element SampledValueControl define an edit wizard that with muticast attribute set to false - deprecated looks like the latest snapshot"] = -` - -
    - - - - - - - - - - - SmpPerPeriod - - - SmpPerSec - - - SecPerSmp - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an edit wizard that with muticast attribute set to false - deprecated looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an edit wizard that with multicast set to treu looks like the latest snapshot"] = -` - -
    - - - - - - - - - SmpPerPeriod - - - SmpPerSec - - - SecPerSmp - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an edit wizard that with multicast set to treu looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the first page looks like the latest snapshot"] = -` -
    - - - - - - - - - SmpPerPeriod - - - SmpPerSec - - - SecPerSmp - - - - - - - - - None - - - Signature - - - SignatureAndEncryption - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the first page looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the second page looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the second page looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the third page looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the third page looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the fourth page looks like the latest snapshot"] = -` -
    - - -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an create wizard that with existing ConnectedAP element in the Communication section the fourth page looks like the latest snapshot */ - -snapshots["Wizards for SCL element SampledValueControl define an create wizard that with missing ConnectedAP element in the Communication section the third page having a warning message "] = -` -
    -

    - [smv.missingaccp] -

    -
    - - - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define an create wizard that with missing ConnectedAP element in the Communication section the third page having a warning message */ - -snapshots["Wizards for SCL element SampledValueControl define a select wizard that looks like the latest snapshot"] = -` -
    - - - - MSVCB01 - - - IED2>>CBSW>MSVCB01 - - - - - MSVCB01 - - - IED3>>MU01>MSVCB01 - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SampledValueControl define a select wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/smv.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/smv.test.snap.js deleted file mode 100644 index 66ae6fd337..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/smv.test.snap.js +++ /dev/null @@ -1,60 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element SMV include an edit wizard that looks like the latest snapshot"] = -` -
    - - - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SMV include an edit wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/smvopts.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/smvopts.test.snap.js deleted file mode 100644 index d42b83ef50..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/smvopts.test.snap.js +++ /dev/null @@ -1,60 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL SmvOpts element define an edit wizard that looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL SmvOpts element define an edit wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/sub-equipment.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/sub-equipment.test.snap.js deleted file mode 100644 index 1420a2f723..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/sub-equipment.test.snap.js +++ /dev/null @@ -1,275 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL SubEquipment element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - A - - - B - - - C - - - N - - - All - - - None - - - AB - - - BC - - - CA - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL SubEquipment element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL SubEquipment element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - A - - - B - - - C - - - N - - - All - - - None - - - AB - - - BC - - - CA - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL SubEquipment element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/subfunction.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/subfunction.test.snap.js deleted file mode 100644 index 626bb08024..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/subfunction.test.snap.js +++ /dev/null @@ -1,99 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL Function element define an create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Function element define an create wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL Function element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL Function element define an edit wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/subnetwork.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/subnetwork.test.snap.js deleted file mode 100644 index 0c85cb2633..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/subnetwork.test.snap.js +++ /dev/null @@ -1,174 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element SubNetwork include an edit wizard that with existing BitRate child element looks like the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SubNetwork include an edit wizard that with existing BitRate child element looks like the latest snapshot */ - -snapshots["Wizards for SCL element SubNetwork include an edit wizard that with missing BitRate child element looks like the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SubNetwork include an edit wizard that with missing BitRate child element looks like the latest snapshot */ - -snapshots["Wizards for SCL element SubNetwork include an create wizard that looks like the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element SubNetwork include an create wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/substation.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/substation.test.snap.js deleted file mode 100644 index 5bb1393b26..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/substation.test.snap.js +++ /dev/null @@ -1,85 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element Substation edit existing Substation looks like the latest snapshot"] = -` -
    - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element Substation edit existing Substation looks like the latest snapshot */ - -snapshots["Wizards for SCL element Substation add new Substation looks like the latest snapshot"] = -` -
    - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL element Substation add new Substation looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/tapchanger.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/tapchanger.test.snap.js deleted file mode 100644 index a79d4a11c5..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/tapchanger.test.snap.js +++ /dev/null @@ -1,110 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL TapChanger element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL TapChanger element define an edit wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL TapChanger element define a create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL TapChanger element define a create wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/terminal.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/terminal.test.snap.js deleted file mode 100644 index 7b4ff4570a..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/terminal.test.snap.js +++ /dev/null @@ -1,48 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL element Terminal looks like the latest snapshot"] = -` -
    - - - - - - -
    - - -
    -`; -/* end snapshot Wizards for SCL element Terminal looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/transformerwinding.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/transformerwinding.test.snap.js deleted file mode 100644 index 195097a35c..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/transformerwinding.test.snap.js +++ /dev/null @@ -1,111 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL TransformerWinding element define an edit wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL TransformerWinding element define an edit wizard that looks like the the latest snapshot */ - -snapshots["Wizards for SCL TransformerWinding element define a create wizard that looks like the the latest snapshot"] = -` -
    - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL TransformerWinding element define a create wizard that looks like the the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/__snapshots__/trgops.test.snap.js b/packages/plugins/test/unit/wizards/__snapshots__/trgops.test.snap.js deleted file mode 100644 index 26d16ef8c1..0000000000 --- a/packages/plugins/test/unit/wizards/__snapshots__/trgops.test.snap.js +++ /dev/null @@ -1,60 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["Wizards for SCL TrgOps element define an edit wizard that looks like the latest snapshot"] = -` -
    - - - - - - - - - - -
    - - - - -
    -`; -/* end snapshot Wizards for SCL TrgOps element define an edit wizard that looks like the latest snapshot */ - diff --git a/packages/plugins/test/unit/wizards/abstractda.test.ts b/packages/plugins/test/unit/wizards/abstractda.test.ts deleted file mode 100644 index 5e0dc217a9..0000000000 --- a/packages/plugins/test/unit/wizards/abstractda.test.ts +++ /dev/null @@ -1,258 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - isCreate, - isDelete, - isReplace, - Create, - Replace - } from '@openscd/core/foundation/deprecated/editor.js'; -import { - getValAction, - wizardContent, -} from '../../../src/wizards/abstractda.js'; -import { regExp, regexString } from '../../foundation.js'; - -describe('abstractda wizards', () => { - describe('getValAction', () => { - const abstractda = new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement; - const oldVal = new DOMParser().parseFromString( - `oldVal`, - 'application/xml' - ).documentElement; - - it('updates a Val child element when changed', () => { - const editorAction = getValAction(oldVal, 'newVal', abstractda); - expect(editorAction).to.satisfy(isReplace); - }); - - it('properly updates an new Val', () => { - const editorAction = getValAction(oldVal, 'newVal', abstractda); - expect(editorAction.new.element.textContent?.trim()).to.equal('newVal'); - }); - - it('creates a Val child element when missing', () => { - const editorAction = getValAction(null, 'newVal', abstractda); - expect(editorAction).to.satisfy(isCreate); - }); - - it('properly creates new Val', () => { - const editorAction = getValAction(null, 'newVal', abstractda); - expect(editorAction.new.element.textContent?.trim()).to.equal('newVal'); - }); - - it('remove a Val child element if present', () => { - const editorAction = getValAction(oldVal, null, abstractda); - expect(editorAction).to.satisfy(isDelete); - }); - }); - - describe('renderWizard', () => { - let doc: XMLDocument; - let data: Element; - let element: OscdWizards; - let enumTypes: string[]; - let daTypes: string[]; - let nameTextField: WizardTextField; - let valSelect: WizardSelect; - let valTextField: WizardTextField; - let bTypeSelect: WizardSelect; - let typeSelect: WizardSelect; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/abstractda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - data = doc.querySelector('DataTypeTemplates')!; - const types = Array.from(data.querySelectorAll('DAType,EnumType')); - enumTypes = Array.from(data.querySelectorAll('EnumType')).map( - enumtype => enumtype.getAttribute('id')! - ); - daTypes = Array.from(data.querySelectorAll('DAType')).map( - enumtype => enumtype.getAttribute('id')! - ); - const wizard = [ - { - title: 'title', - content: wizardContent( - '', - null, - 'Enum', - types, - 'Dummy_ctlModel', - null, - null, - null, - 'status-only', - data - ), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - nameTextField = element.wizardUI.dialog!.querySelector( - 'wizard-textfield[label="name"]' - )!; - bTypeSelect = element.wizardUI.dialog!.querySelector( - 'wizard-select[label="bType"]' - )!; - valSelect = element.wizardUI.dialog!.querySelector( - 'wizard-select[label="Val"]' - )!; - valTextField = element.wizardUI.dialog!.querySelector( - 'wizard-textfield[label="Val"]' - )!; - typeSelect = element.wizardUI.dialog!.querySelector( - 'wizard-select[label="type"]' - )!; - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }); - - it('edits name attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty( - regexString(regExp.abstractDataAttributeName, 1, 32), - async name => { - nameTextField.value = name; - await nameTextField.requestUpdate(); - expect(nameTextField.checkValidity()).to.be.true; - } - ) - ); - }); - - it('rejects name attribute starting with decimals', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => { - nameTextField.value = name; - await nameTextField.requestUpdate(); - expect(nameTextField.checkValidity()).to.be.false; - }) - ); - }); - - it('disables the type field in case bType is not Enum nor Struct', async () => { - bTypeSelect.value = 'BOOLEAN'; - await typeSelect.requestUpdate(); - expect(typeSelect.disabled).to.be.true; - }); - - it('pre-selects the type in the type field in case bType is Enum or Struct', async () => { - await typeSelect.requestUpdate(); - expect(typeSelect.value).to.be.equal('Dummy_ctlModel'); - }); - - it('pre-selects the type in the type field bType has re-selected to the initial bType', async () => { - bTypeSelect.value = 'BOOLEAN'; - await typeSelect.requestUpdate(); - expect(typeSelect.value).to.not.be.equal('Dummy_ctlModel'); - bTypeSelect.value = 'Enum'; - await typeSelect.requestUpdate(); - expect(typeSelect.value).to.be.equal('Dummy_ctlModel'); - }); - - it('filters EnumType in the type field if bType is Enum ', async () => { - bTypeSelect.value = 'Enum'; - await typeSelect.requestUpdate(); - const typeList = typeSelect.items - .filter(item => !item.noninteractive) - .map(item => item.value); - expect(typeList.length).to.equal(enumTypes.length); - }); - - it('filters DAType in the type field if bType is Struct ', async () => { - bTypeSelect.value = 'Struct'; - await typeSelect.requestUpdate(); - const typeList = typeSelect.items - .filter(item => !item.noninteractive) - .map(item => item.value); - expect(typeList.length).to.equal(daTypes.length); - }); - - it('selects first DAType item when bType changes from enum to Struct', async () => { - bTypeSelect.value = 'Enum'; - await typeSelect.requestUpdate(); - bTypeSelect.value = 'Struct'; - await typeSelect.requestUpdate(); - expect(typeSelect.value).to.equal(daTypes[0]); - }); - - it('renders the Val field as wizard-select when bType is Enum', async () => { - bTypeSelect.value = 'Enum'; - await valSelect.requestUpdate(); - await valTextField.requestUpdate(); - expect(valSelect.style.display).to.equal(''); - expect(valTextField.style.display).to.equal('none'); - }); - - it('does not render the Val field when bType is Struct', async () => { - bTypeSelect.value = 'Struct'; - await valSelect.requestUpdate(); - await valTextField.requestUpdate(); - expect(valSelect.style.display).to.equal('none'); - expect(valTextField.style.display).to.equal('none'); - }); - - it('renders the Val field as wizard-textfield in all other cases', async () => { - bTypeSelect.value = 'Struct'; - await valSelect.requestUpdate(); - await valTextField.requestUpdate(); - expect(valSelect.style.display).to.equal('none'); - expect(valTextField.style.display).to.equal('none'); - }); - - it('shows Val form the file in the Val fields', async () => { - await valSelect.requestUpdate(); - expect(valSelect.value).to.equal('status-only'); - }); - - it('filters Val selection for the initially loaded Enum', async () => { - await valSelect.requestUpdate(); - expect(valSelect.items.length).to.equal( - data.querySelectorAll(`EnumType[id="${typeSelect.value}"] > EnumVal`) - .length - ); - }); - - it('filters Val selection for bType Enum and ctlModelKind', async () => { - bTypeSelect.value = 'Enum'; - await valSelect.requestUpdate(); - expect(valSelect.items.length).to.equal( - data.querySelectorAll(`EnumType[id="${typeSelect.value}"] > EnumVal`) - .length - ); - }); - - it('filters Val selection for bType Enum and HealthKind', async () => { - bTypeSelect.value = 'Enum'; - typeSelect.value = 'Dummy_Health'; - await valSelect.requestUpdate(); - expect(valSelect.items.length).to.equal( - data.querySelectorAll(`EnumType[id="${typeSelect.value}"] > EnumVal`) - .length - ); - }); - - it('does not filters Val selection it bType is not Enum', async () => { - bTypeSelect.value = 'Struct'; - typeSelect.value = 'Dummy_origin'; - await valSelect.requestUpdate(); - expect(valSelect.items.length).to.equal(0); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/address.test.ts b/packages/plugins/test/unit/wizards/address.test.ts deleted file mode 100644 index caae4d51be..0000000000 --- a/packages/plugins/test/unit/wizards/address.test.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - getValue, - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - Create, - Delete -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - contentGseOrSmvWizard, - updateAddress, -} from '../../../src/wizards/address.js'; - -function addressContent( - inputs: WizardInputElement[] -): Record { - const addressContent: Record = {}; - - addressContent['MAC-Address'] = getValue( - inputs.find(i => i.label === 'MAC-Address')! - ); - addressContent['APPID'] = getValue(inputs.find(i => i.label === 'APPID')!); - addressContent['VLAN-ID'] = getValue( - inputs.find(i => i.label === 'VLAN-ID')! - ); - addressContent['VLAN-PRIORITY'] = getValue( - inputs.find(i => i.label === 'VLAN-PRIORITY')! - ); - - return addressContent; -} - -describe('address', () => { - let doc: XMLDocument; - let element: OscdWizards; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/gsecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('renderGseSmvAddress', () => { - beforeEach(async () => { - const gse = doc.querySelector( - 'GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]' - )!; - - const hasInstType = Array.from(gse.querySelectorAll('Address > P')).some( - pType => pType.getAttribute('xsi:type') - ); - - const attributes: Record = {}; - ['MAC-Address', 'APPID', 'VLAN-ID', 'VLAN-PRIORITY'].forEach(key => { - if (!attributes[key]) - attributes[key] = - gse.querySelector(`Address > P[type="${key}"]`)?.innerHTML.trim() ?? - null; - }); - - const wizard = [ - { - title: 'title', - content: contentGseOrSmvWizard({ hasInstType, attributes }), - }, - ]; - - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - }); - - describe('updateAddress', () => { - let gse: Element; - let inputs: WizardInputElement[]; - let wizard: Wizard; - - describe('with exiting address element', () => { - beforeEach(async () => { - gse = doc.querySelector( - 'GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]' - )!; - - const hasInstType = Array.from( - gse.querySelectorAll('Address > P') - ).some(pType => pType.getAttribute('xsi:type')); - - const attributes: Record = {}; - ['MAC-Address', 'APPID', 'VLAN-ID', 'VLAN-PRIORITY'].forEach(key => { - if (!attributes[key]) - attributes[key] = - gse - .querySelector(`Address > P[type="${key}"]`) - ?.innerHTML.trim() ?? null; - }); - - wizard = [ - { - title: 'asdas', - content: contentGseOrSmvWizard({ hasInstType, attributes }), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('does not update a Address element when no attribute has changed', () => { - const actions = updateAddress(gse, addressContent(inputs), false); - expect(actions).to.be.empty; - }); - - it('update a Address element when VLAN ID gets created', async () => { - const input = inputs[2]; - const type = input.label; - const newValue = 'newValue'; - - input.maybeValue = newValue; - await input.requestUpdate(); - - const actions = updateAddress(gse, addressContent(inputs), false); - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.be.undefined; - expect( - newElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(newValue); - expect( - newElement.querySelector(`P[type="${type}"]`) - ).to.not.have.attribute('xsi:type', `tP_${type}`); - }); - - it('update a Address element when at least one attribute changes', async () => { - for (const rawInput of inputs) { - const input = - rawInput instanceof WizardTextField - ? rawInput - : rawInput; - - const type = input.label; - const newValue = 'newValue'; - const oldValue = input.value || undefined; - - input.maybeValue = newValue; - await input.requestUpdate(); - - const actions = updateAddress(gse, addressContent(inputs), false); - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(oldValue); - expect( - newElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(newValue); - expect( - newElement.querySelector(`P[type="${type}"]`) - ).to.not.have.attribute('xsi:type', `tP_${type}`); - } - }); - - it('update a Address element when status of instType has changed', async () => { - for (const rawInput of inputs) { - const input = - rawInput instanceof WizardTextField - ? rawInput - : rawInput; - - const type = input.label; - const newValue = input.value; - const oldValue = input.value || undefined; - - input.maybeValue = newValue; - await input.requestUpdate(); - - const actions = updateAddress(gse, addressContent(inputs), true); - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(oldValue); - expect( - newElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(newValue); - expect( - newElement.querySelector(`P[type="${type}"]`) - ).to.have.attribute('xsi:type', `tP_${type}`); - } - }); - }); - - describe('with missing address element', () => { - beforeEach(async () => { - gse = doc.querySelector( - 'GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB2"]' - )!; - - const hasInstType = Array.from( - gse.querySelectorAll('Address > P') - ).some(pType => pType.getAttribute('xsi:type')); - - const attributes: Record = {}; - ['MAC-Address', 'APPID', 'VLAN-ID', 'VLAN-PRIORITY'].forEach(key => { - if (!attributes[key]) - attributes[key] = - gse - .querySelector(`Address > P[type="${key}"]`) - ?.innerHTML.trim() ?? null; - }); - - wizard = [ - { - title: 'asdas', - content: contentGseOrSmvWizard({ hasInstType, attributes }), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('creates a Address element when at least one attribute changes', async () => { - for (const rawInput of inputs) { - const input = - rawInput instanceof WizardTextField - ? rawInput - : rawInput; - - if (input.maybeValue === null) { - input.nullSwitch?.click(); - await input.requestUpdate(); - } - - const type = input.label; - const newValue = 'newValue'; - input.value = newValue; - await input.requestUpdate(); - - const actions = updateAddress(gse, addressContent(inputs), false); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isCreate); - const newElement = (actions[0]).new.element; - expect( - newElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(newValue); - expect( - newElement.querySelector(`P[type="${type}"]`) - ).to.not.have.attribute('xsi:type', `tP_${type}`); - } - }); - - it('update a Address element when status of instType has changed', async () => { - for (const rawInput of inputs) { - const input = - rawInput instanceof WizardTextField - ? rawInput - : rawInput; - - if (input.maybeValue === null) { - input.nullSwitch?.click(); - await input.requestUpdate(); - } - - const type = input.label; - const newValue = input.value; - - input.value = newValue; - await input.requestUpdate(); - const actions = updateAddress(gse, addressContent(inputs), true); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isCreate); - const newElement = (actions[0]).new.element; - expect( - newElement.querySelector(`P[type="${type}"]`)?.textContent?.trim() - ).to.equal(newValue); - expect( - newElement.querySelector(`P[type="${type}"]`) - ).to.have.attribute('xsi:type', `tP_${type}`); - } - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/bay.test.ts b/packages/plugins/test/unit/wizards/bay.test.ts deleted file mode 100644 index d454652a63..0000000000 --- a/packages/plugins/test/unit/wizards/bay.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import { - WizardInputElement, - WizardActor, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - isSimple, - ComplexAction -} from '@openscd/core/foundation/deprecated/editor.js'; -import '@openscd/open-scd/src/wizard-textfield.js'; -import { createAction } from '../../../src/wizards/bay.js'; -import { replaceNamingAttributeWithReferencesAction } from '../../../src/wizards/foundation/actions.js'; - -describe('BayEditor', () => { - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - let inputs: WizardInputElement[]; - beforeEach(async () => { - inputs = await Promise.all( - ['name', 'desc'].map( - label => - >( - fixture(html``) - ) - ) - ); - }); - - function getAndValidComplexAction(wizardActor: WizardActor): ComplexAction { - const editorActions = wizardActor(inputs, newWizard()); - expect(editorActions.length).to.equal(1); - expect(editorActions[0]).to.not.satisfy(isSimple); - return editorActions[0]; - } - - describe('createAction', () => { - let parent: Element; - beforeEach(() => { - parent = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns a Create EditorAction', () => { - const wizardAction = createAction(parent); - expect(wizardAction(inputs, newWizard())[0]).to.satisfy(isCreate); - }); - }); - - describe('updateAction', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which retruns one EditorAction', () => { - const wizardAction = replaceNamingAttributeWithReferencesAction(element, 'bay.action.updateBay'); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions.length).to.equal(1); - }); - - it('returns a WizardAction which returns an Update EditorAction', () => { - const wizardAction = replaceNamingAttributeWithReferencesAction(element, 'bay.action.updateBay'); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[0]).to.satisfy(isReplace); - }); - - describe('with no change in element Bay', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - ` - `, - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns empty EditorAction array', () => { - const wizardAction = replaceNamingAttributeWithReferencesAction(element, 'bay.action.updateBay'); - expect(wizardAction(inputs, newWizard()).length).to.equal(0); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/bda.test.ts b/packages/plugins/test/unit/wizards/bda.test.ts deleted file mode 100644 index 95d634f009..0000000000 --- a/packages/plugins/test/unit/wizards/bda.test.ts +++ /dev/null @@ -1,296 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { wizardContent } from '../../../src/wizards/abstractda.js'; -import { createBDaAction, updateBDaAction } from '../../../src/wizards/bda.js'; - -describe('bda wizards', () => { - describe('updateBDaAction', () => { - let doc: XMLDocument; - let data: Element; - let element: OscdWizards; - - const bda = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/abstractda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - data = doc.querySelector('DataTypeTemplates')!; - const types = Array.from(data.querySelectorAll('DAType,EnumType')); - wizard = [ - { - title: 'title', - content: wizardContent( - 'orCat', - null, - 'Enum', - types, - 'Dummy_orCategory', - null, - null, - null, - null, - data - ), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('does not update a BDA element when no attribute nor Val has changed', () => { - const editorAction = updateBDaAction(bda); - expect(editorAction(inputs, newWizard())).to.be.empty; - }); - it('update a BDA element when only name attribute changed', async () => { - inputs[0].value = 'myOrName'; - await (inputs[0]).requestUpdate(); - const editorAction = updateBDaAction(bda); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a BDA element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - const editorAction = updateBDaAction(bda); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a BDA element when only bType attribute changed', async () => { - inputs[2].value = 'BOOLEAN'; - await (inputs[2]).requestUpdate(); - const editorAction = updateBDaAction(bda); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a BDA element when type attribute changed to null', async () => { - inputs[2].value = 'BOOLEAN'; - await (inputs[2]).requestUpdate(); - const editorAction = updateBDaAction(bda); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - const updateAction = editorAction(inputs, newWizard())[0]; - expect(updateAction.old.element).to.have.attribute('type'); - expect(updateAction.new.element).to.not.have.attribute('type'); - }); - it('update a BDA element when sAddr attribute changed', async () => { - const input = inputs[4]; - input.nullSwitch?.click(); - input.value = 'mysAddr'; - await input.requestUpdate(); - const editorAction = updateBDaAction(bda); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('sAddr'); - expect(updateAction.new.element).to.have.attribute('sAddr', 'mysAddr'); - }); - it('update a BDA element when valKind attribute changed', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - input.value = 'RO'; - await input.requestUpdate(); - const editorAction = updateBDaAction(bda); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('valKind'); - expect(updateAction.new.element).to.have.attribute('valKind', 'RO'); - }); - it('update a BDA element when valImport attribute changed', async () => { - const input = inputs[6]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateBDaAction(bda); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('valImport'); - expect(updateAction.new.element).to.have.attribute('valImport', 'true'); - }); - it('creates a Val child Val attribute changes from null to something', async () => { - const input = inputs[7]; - input.nullSwitch?.click(); - input.value = 'bay-control'; - await input.requestUpdate(); - const editorAction = updateBDaAction(bda); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isCreate); - const updateAction = updateActions[0]; - expect( - (updateAction.new.element) - .querySelector('Val') - ?.textContent?.trim() - ).to.not.equal('bay-control'); - }); - }); - - describe('createBDaAction', () => { - let doc: XMLDocument; - let data: Element; - let element: OscdWizards; - - const daType = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/abstractda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - data = doc.querySelector('DataTypeTemplates')!; - const types = Array.from(data.querySelectorAll('DAType,EnumType')); - wizard = [ - { - title: 'title', - content: wizardContent( - 'myNewBDA', - null, - 'INT32', - types, - '', - null, - null, - null, - null, - data - ), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('creates a BDA element', () => { - const editorAction = createBDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect(createAction.new.element).to.have.attribute('name', 'myNewBDA'); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.have.attribute('bType', 'INT32'); - expect(createAction.new.element).to.not.have.attribute('type'); - expect(createAction.new.element).to.not.have.attribute('sAddrs'); - expect(createAction.new.element).to.not.have.attribute('valKind'); - expect(createAction.new.element).to.not.have.attribute('valImport'); - }); - it('creates yet another BDA element with different attribute setting', async () => { - const desc = inputs[1]; - const bType = inputs[2]; - const sAddr = inputs[4]; - const valKind = inputs[5]; - const valImport = inputs[6]; - - desc.nullSwitch?.click(); - desc.value = 'myDesc'; - await desc.requestUpdate(); - bType.value = 'Struct'; - await bType.requestUpdate(); - sAddr.nullSwitch?.click(); - sAddr.value = 'mysAddr'; - await sAddr.requestUpdate(); - valKind.nullSwitch?.click(); - valKind.value = 'Conf'; - await valKind.requestUpdate(); - valImport.nullSwitch?.click(); - valImport.value = 'false'; - await valImport.requestUpdate(); - - const editorAction = createBDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect(createAction.new.element).to.have.attribute('name', 'myNewBDA'); - expect(createAction.new.element).to.have.attribute('desc', 'myDesc'); - expect(createAction.new.element).to.have.attribute('bType', 'Struct'); - expect(createAction.new.element).to.have.attribute( - 'type', - 'AnalogueValue_i' - ); - expect(createAction.new.element).to.have.attribute('sAddr', 'mysAddr'); - expect(createAction.new.element).to.have.attribute('valKind', 'Conf'); - expect(createAction.new.element).to.have.attribute('valImport', 'false'); - }); - it('creates Val childelement when checked', async () => { - const Val = inputs[8]; - - Val.nullSwitch?.click(); - Val.value = '8123'; - await Val.requestUpdate(); - - const editorAction = createBDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect( - (createAction.new.element) - .querySelector('Val') - ?.textContent?.trim() - ).to.equal('8123'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/clientln.test.ts b/packages/plugins/test/unit/wizards/clientln.test.ts deleted file mode 100644 index 114ebe2cfb..0000000000 --- a/packages/plugins/test/unit/wizards/clientln.test.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { List } from '@material/mwc-list'; -import { ListItem } from '@material/mwc-list/mwc-list-item'; - -import '../../../src/editors/substation/zeroline-pane.js'; -import { IedEditor } from '../../../src/editors/substation/ied-editor.js'; -import { ZerolinePane } from '../../../src/editors/substation/zeroline-pane.js'; - -describe('clientln wizards', () => { - let doc: Document; - let parent: MockWizardEditor; - let element: ZerolinePane; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/comm-map.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = await fixture( - html`` - ); - - await parent.updateComplete; - element = parent.querySelector('zeroline-pane')!; - await element.updateComplete; - element.showieds.click(); - await element.requestUpdate(); - }); - - describe('createClientLnWizard', () => { - let ied1: IedEditor; - let primaryAction: HTMLElement; - let reportCbs: ListItem[]; - let logicalnodes: ListItem[]; - - beforeEach(async () => { - if (!element.showieds.on) element.showieds.click(); - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - ied1 = element.shadowRoot!.querySelector('ied-editor')!; - ied1.connectReport.click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - - primaryAction = parent.wizardUI.dialog!.querySelector( - 'mwc-button[slot="primaryAction"]' - )!; - reportCbs = - parent.wizardUI.dialog!.querySelector('#sourcelist')!.items; - - logicalnodes = - parent.wizardUI.dialog!.querySelector('#sinklist')!.items; - }); - - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - - it('add ClientLN referencing to logical nodes in AccessPoint', async () => { - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN' - ) - )?.to.not.exist; - reportCbs[2].click(); - logicalnodes[0].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN[iedName="IED1"][apRef="P1"][prefix="DC"][lnClass="CILO"][lnInst="1"]' - ) - )?.to.exist; - }); - - it('does not add an already existing ClientLN referencing to logical nodes in AccessPoint', async () => { - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ClientLN[iedName="IED1"][apRef="P1"][prefix="DC"][lnClass="CILO"][lnInst="1"]' - ).length - )?.to.equal(1); - reportCbs[0].click(); - logicalnodes[0].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ClientLN[iedName="IED1"][apRef="P1"][prefix="DC"][lnClass="CILO"][lnInst="1"]' - ).length - )?.to.equal(1); - }); - it('add ClientLN referencing to LN0', async () => { - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN' - ) - )?.to.not.exist; - reportCbs[2].click(); - logicalnodes[14].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN[iedName="IED1"][apRef="P1"][ldInst="Disconnectors"][lnClass="LLN0"]' - ) - )?.to.exist; - }); - it('does not add an already existing ClientLN referencing to LN0', async () => { - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ' + - 'ClientLN[iedName="IED3"][apRef="P1"][ldInst="Disconnectors"][lnClass="LLN0"]' - ).length - )?.to.equal(1); - reportCbs[0].click(); - logicalnodes[14].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ClientLN[iedName="IED3"][apRef="P1"][ldInst="Disconnectors"][lnClass="LLN0"]' - ).length - )?.to.equal(1); - }); - it('add ClientLN referencing to logical nodes located in logical devices', async () => { - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN' - ) - )?.to.not.exist; - reportCbs[2].click(); - logicalnodes[5].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportEmpty"] ClientLN[iedName="IED1"][apRef="P1"][ldInst="Disconnectors"][prefix="DC"][lnClass="XSWI"][lnInst="1"]' - ) - )?.to.exist; - }); - it('does not add an already existing ClientLN referencing to to logical nodes located in logical devices', async () => { - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ClientLN[iedName="IED1"][apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="XCBR"][lnInst="1"]' - ).length - )?.to.equal(1); - reportCbs[0].click(); - logicalnodes[0].click(); - await parent.updateComplete; - primaryAction.click(); - await parent.updateComplete; - expect( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl[name="ReportCb"] ClientLN[iedName="IED1"][apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="XCBR"][lnInst="1"]' - ).length - )?.to.equal(1); - }); - it('disabled report control blocks when the number of ClientLns reach the max attribute', async () => { - expect(reportCbs[1]).to.have.attribute('disabled'); - }); - }).timeout(5000); - - describe('selectClientLnWizard', () => { - let commMappings: List; - - beforeEach(async () => { - element.commmap.click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - commMappings = ( - parent.wizardUI.dialog?.querySelector('filtered-list') - ); - - commMappings.items[1].click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - }); - - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - - it('filteres ClientLNs to one receiving IED', async () => { - expect( - parent.wizardUI.dialog?.querySelectorAll('mwc-check-list-item').length - ).to.equal( - doc.querySelectorAll( - 'IED[name="IED2"] ReportControl ClientLN[iedName="IED1"]' - ).length - ); - }); - - it('allowes to remove ClientLNs', async () => { - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[2].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - )).click(); - await parent.updateComplete; - expect( - doc.querySelector( - 'ClientLN[iedName="IED1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"]' - ) - ).to.be.null; - }); - }); -}).timeout(5000); diff --git a/packages/plugins/test/unit/wizards/commmap.test.ts b/packages/plugins/test/unit/wizards/commmap.test.ts deleted file mode 100644 index f597917ba9..0000000000 --- a/packages/plugins/test/unit/wizards/commmap.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../src/editors/substation/zeroline-pane.js'; -import { - getSinkReferences, - getSourceReferences, -} from '../../../src/wizards/commmap-wizards.js'; -import { ZerolinePane } from '../../../src/editors/substation/zeroline-pane.js'; - -describe('communication mapping wizard', () => { - let doc: Document; - let parent: OscdWizards; - let element: ZerolinePane; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/comm-map.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = await fixture( - html`` - ); - - element = parent.querySelector('zeroline-pane')!; - element.commmap.click(); - await element.updateComplete; - await parent.updateComplete; - }); - - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - - it('closes wizard on secondary action', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog!.querySelector( - 'mwc-button[slot="secondaryAction"]' - ) - )).click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - expect(parent.wizardUI.dialogs.length).to.equal(0); - }); - - describe('getSinkReferences', () => { - it('returns an array of all ClientLN`s for doc as input', () => { - const clientlns = getSinkReferences(doc); - expect(clientlns).to.have.length(6); - expect( - clientlns[0].isEqualNode( - doc.querySelector('ReportControl[name="ReportCb"] ClientLN') - ) - )?.to.be.true; - }); - it('returns an array all ClientLN`s connected to an IED - send and receive', () => { - const clientlns = getSinkReferences( - doc.querySelector('IED[name="IED1"]')! - ); - expect(clientlns).to.have.length(5); - expect( - clientlns[0].isEqualNode( - doc.querySelector('ReportControl[name="ReportCb"] ClientLN') - ) - )?.to.be.true; - }); - }); - - describe('getSourceReferences', () => { - it('returns an array of all ExtRef`s with doc as inputs', () => { - const extRefs = getSourceReferences(doc); - expect(extRefs).to.have.length(20); - expect(extRefs[0].isEqualNode(doc.querySelector('ExtRef'))).to.be.true; - }); - it('returns an array of all ExtRef`s connected to an IED - send and receive', () => { - const extRefs = getSourceReferences( - doc.querySelector('IED[name="IED2"]')! - ); - expect(extRefs).to.have.length(6); - expect( - extRefs[2].isEqualNode(doc.querySelector('IED[name="IED2"] ExtRef')) - ).to.be.true; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/conductingequipment.test.ts b/packages/plugins/test/unit/wizards/conductingequipment.test.ts deleted file mode 100644 index f42374212a..0000000000 --- a/packages/plugins/test/unit/wizards/conductingequipment.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { Create, isCreate } from '@openscd/core/foundation/deprecated/editor.js'; -import { fetchDoc } from './test-support.js'; -import { createConductingEquipmentWizard } from '../../../src/wizards/conductingequipment.js'; - -describe('Wizards for SCL element ConductingEquipment', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - describe('defines a create wizard that', () => { - let parent: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/valid2007B.scd'); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('when adding an earth switch', () => { - describe('with existing ground cNode in the same VoltageLevel', () => { - beforeEach(async () => { - parent = doc.querySelector('Bay')!; - - element = await fixture( - html`` - ); - const wizard = createConductingEquipmentWizard(parent); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - it('does not create a new ConnectivityNode', async () => { - inputs[0].value = 'ERS'; - inputs[1].value = 'QC9'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - }); - - it('does set the Terminals attributes correctly', async () => { - inputs[0].value = 'ERS'; - inputs[1].value = 'QC9'; - - await element.requestUpdate(); - await primaryAction.click(); - - const action = actionEvent.args[0][0].detail.action; - const terminal = (action.new.element).querySelector( - 'Terminal' - )!; - expect(terminal).to.have.attribute('substationName', 'AA1'); - expect(terminal).to.have.attribute('voltageLevelName', 'E1'); - expect(terminal).to.have.attribute('bayName', 'COUPLING_BAY'); - expect(terminal).to.have.attribute( - 'connectivityNode', - 'AA1/E1/COUPLING_BAY/grounded' - ); - }); - }); - - describe('with missing ground cNode in the same VoltageLevel', () => { - beforeEach(async () => { - parent = doc.querySelector('VoltageLevel[name="J1"] > Bay')!; - - element = await fixture( - html`` - ); - const wizard = createConductingEquipmentWizard(parent); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does create a new ConnectivityNode', async () => { - inputs[0].value = 'ERS'; - inputs[1].value = 'QC9'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledTwice; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const action = actionEvent.args[1][0].detail.action; - expect((action.new.element).tagName).to.equal( - 'ConnectivityNode' - ); - }); - - it('does set the pathName of ConnectivityNode correctly', async () => { - inputs[0].value = 'ERS'; - inputs[1].value = 'QC9'; - - await element.requestUpdate(); - await primaryAction.click(); - - const action = actionEvent.args[1][0].detail.action; - expect(action.new.element).to.have.attribute( - 'pathName', - 'AA1/J1/Bay1/grounded' - ); - expect(action.new.element).to.have.attribute( - 'name', - 'grounded' - ); - }); - - it('does set the Terminals attributes correctly', async () => { - inputs[0].value = 'ERS'; - inputs[1].value = 'QC9'; - - await element.requestUpdate(); - await primaryAction.click(); - - const action = actionEvent.args[0][0].detail.action; - const terminal = (action.new.element).querySelector( - 'Terminal' - )!; - expect(terminal).to.have.attribute('substationName', 'AA1'); - expect(terminal).to.have.attribute('voltageLevelName', 'J1'); - expect(terminal).to.have.attribute('bayName', 'Bay1'); - expect(terminal).to.have.attribute( - 'connectivityNode', - 'AA1/J1/Bay1/grounded' - ); - }); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/connectedap-c.test.ts b/packages/plugins/test/unit/wizards/connectedap-c.test.ts deleted file mode 100644 index ce20c02be5..0000000000 --- a/packages/plugins/test/unit/wizards/connectedap-c.test.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base.js'; - -import { createConnectedApWizard } from '../../../src/wizards/connectedap.js'; -import { newWizardEvent } from '@openscd/open-scd/src/foundation.js'; - -function isAllMacUnique(parent: Element, serviceType: 'GSE' | 'SMV'): boolean { - const allMacs = Array.from( - parent.ownerDocument.querySelectorAll( - `${serviceType} > Address > P[type="MAC-Address"]` - ) - ).map(pType => pType.textContent!); - - const set = new Set(allMacs); - - return allMacs.length === set.size; -} - -function isAllAppIdUnique( - parent: Element, - serviceType: 'GSE' | 'SMV' -): boolean { - const allMacs = Array.from( - parent.ownerDocument.querySelectorAll( - `${serviceType} > Address > P[type="APPID"]` - ) - ).map(pType => pType.textContent!); - - const set = new Set(allMacs); - - return allMacs.length === set.size; -} - -async function clickListItem( - element: MockWizardEditor, - values: string[] -): Promise { - Array.from(values).forEach(value => { - element.wizardUI - .dialog!.querySelector( - `mwc-check-list-item[value="${value}"]` - ) - ?.click(); - }); - - await element.updateComplete; - - (( - element.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - - await element.updateComplete; -} - -describe('create wizard for ConnectedAP element', () => { - let doc: XMLDocument; - let element: MockWizardEditor; - let parent: Element; - - beforeEach(async () => { - element = ( - await fixture(html``) - ); - - doc = await fetch('/test/testfiles/wizards/communication.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = doc.querySelector('SubNetwork')!; - const wizard = createConnectedApWizard(parent); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - - /* - inputs = Array.from(element.wizardUI.inputs); - */ - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('it does not allow to add already connected access points', () => { - const disabledItems = Array.from( - element.wizardUI.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ).filter(item => item.disabled); - - for (const item of disabledItems) { - const [iedName, apName] = item.value.split('>'); - expect( - doc.querySelector( - `ConnectedAP[iedName="${iedName}"][apName="${apName}"]` - ) - ).to.exist; - } - }); - - describe('on connecting one new access point', () => { - it('adds a new ConnectedAP element', async () => { - await clickListItem(element, ['GOOSE_Publisher>AP2']); - - expect( - parent.querySelector( - 'ConnectedAP[iedName="GOOSE_Publisher"][apName="AP2"]' - ) - ).to.exist; - }); - - describe('with publishing GSEControl or SampledValueControl', () => { - it('create unique GSE for each GSEControl', async () => { - await clickListItem(element, ['GOOSE_Publisher>AP2']); - expect( - parent.querySelectorAll( - 'ConnectedAP[iedName="GOOSE_Publisher"][apName="AP2"] ' + '> GSE' - ) - ).to.have.length(2); - }); - - it('adds uniques GSE MAC-Address and APPID', async () => { - const value = 'GOOSE_Publisher>AP2'; - await clickListItem(element, [value]); - - expect(isAllMacUnique(parent, 'GSE')).to.be.true; - expect(isAllAppIdUnique(parent, 'GSE')).to.be.true; - }); - - it('create unique SMV for each SampledValueControl', async () => { - await clickListItem(element, ['SMV_Publisher>AP1']); - - expect( - parent.querySelectorAll( - 'ConnectedAP[iedName="SMV_Publisher"][apName="AP1"] ' + '> SMV' - ) - ).to.have.length(2); - }); - - it('adds uniques SMV MAC-Address and APPID', async () => { - const value = 'SMV_Publisher>AP1'; - await clickListItem(element, [value]); - - expect(isAllMacUnique(parent, 'SMV')).to.be.true; - expect(isAllAppIdUnique(parent, 'SMV')).to.be.true; - }); - }); - }); - - describe('on connecting multiple new access point', () => { - it('adds new ConnectedAP element for each selected acc p', async () => { - await clickListItem(element, [ - 'GOOSE_Publisher>AP2', - 'GOOSE_Publisher>AP3', - ]); - - expect( - parent.querySelector( - 'ConnectedAP[iedName="GOOSE_Publisher"][apName="AP2"]' - ) - ).to.exist; - - expect( - parent.querySelector( - 'ConnectedAP[iedName="GOOSE_Publisher"][apName="AP3"]' - ) - ).to.exist; - }); - - describe('with publishing GSEControl or SampledValueControl', () => { - it('create unique GSE for each GSEControl', async () => { - await clickListItem(element, [ - 'GOOSE_Publisher>AP2', - 'GOOSE_Publisher>AP3', - ]); - expect( - parent.ownerDocument.querySelectorAll( - 'ConnectedAP[iedName="GOOSE_Publisher"]' + '> GSE' - ) - ).to.have.length(3); - }); - - it('adds uniques GSE MAC-Address and APPID', async () => { - await clickListItem(element, [ - 'GOOSE_Publisher>AP2', - 'GOOSE_Publisher2>AP1', - ]); - - expect(isAllMacUnique(parent, 'GSE')).to.be.true; - expect(isAllMacUnique(parent, 'GSE')).to.be.true; - }); - - it('create unique SMV for each SampledValueControl', async () => { - await clickListItem(element, [ - 'SMV_Publisher>AP1', - 'SMV_Publisher>AP4', - ]); - - expect( - parent.ownerDocument.querySelectorAll( - 'ConnectedAP[iedName="SMV_Publisher"] ' + '> SMV' - ) - ).to.have.length(3); - }); - - it('adds uniques MAC-Address and APPID', async () => { - await clickListItem(element, [ - 'SMV_Publisher>AP1', - 'SMV_Publisher2>AP1', - ]); - - expect(isAllMacUnique(parent, 'SMV')).to.be.true; - expect(isAllAppIdUnique(parent, 'SMV')).to.be.true; - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/connectedap-pattern.test.ts b/packages/plugins/test/unit/wizards/connectedap-pattern.test.ts deleted file mode 100644 index 3a2f58e3d8..0000000000 --- a/packages/plugins/test/unit/wizards/connectedap-pattern.test.ts +++ /dev/null @@ -1,874 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import fc, { integer, ipV4, nat } from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import '../../../src/editors/communication/connectedap-editor.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; - -import { - ipV6, - ipV6SubNet, - invertedRegex, - regExp, - regexString, -} from '../../foundation.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { editConnectedApWizard } from '../../../src/wizards/connectedap.js'; - -describe('Edit wizard for SCL element ConnectedAP', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - beforeEach(async () => { - element = await fixture( - html`` - ); - }); - - describe('include an edit wizard that', () => { - describe('for Edition 1 projects', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editConnectedApWizard(doc.querySelector('ConnectedAP')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - describe('contains an input to edit P element of type IP', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IP'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV4(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv4), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IP-SUBNET', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IP-SUBNET'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV4(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv4), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IP-GATEWAY', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IP-GATEWAY'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV4(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv4), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-TSEL', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'OSI-TSEL'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(regExp.OSI, 1, 8), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-SSEL', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'OSI-SSEL'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSI, 1, 16), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-PSEL', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'OSI-PSEL'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSI, 1, 16), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-AP-Title', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'OSI-AP-Title'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(regExp.OSIAPi, 1), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSIAPi), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-AP-Invoke', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'OSI-AP-Invoke'); - if (input && (input).maybeValue === null) - await (input).nullSwitch?.click(); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSIid, 1, 5), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSIid), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-AE-Qualifier', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'OSI-AE-Qualifier'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSIid, 1, 5), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSIid), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-AE-Invoke', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'OSI-AE-Invoke'); - if (input && (input).maybeValue === null) - await (input).nullSwitch?.click(); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSIid, 1, 5), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSIid), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type OSI-NSAP', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'OSI-NSAP'); - if (input && (input).maybeValue === null) - await (input).nullSwitch?.click(); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - regexString(regExp.OSI, 1, 40), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type VLAN-ID', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'VLAN-ID'); - if (input && (input).maybeValue === null) - await (input).nullSwitch?.click(); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(regExp.OSI, 3, 3), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type VLAN-PRIORITY', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'VLAN-PRIORITY'); - if (input && (input).maybeValue === null) - await (input).nullSwitch?.click(); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(/^[0-7]$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-7]$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - }); - - describe('for Edition 2 projects', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editConnectedApWizard(doc.querySelector('ConnectedAP')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - describe('contains an input to edit P element of type SNTP-Port', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'SNTP-Port'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - nat({ max: 65535 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type MMS-Port', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'MMS-Port'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - nat({ max: 65535 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type DNSName', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'DNSName'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(/^\S*$/, 1), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - }); - - describe('contains an input to edit P element of type UDP-Port', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'UDP-Port'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - nat({ max: 65535 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type TCP-Port', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'TCP-Port'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - nat({ max: 65535 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type C37-118-IP-Port', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'C37-118-IP-Port'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - integer({ min: 1025, max: 65535 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - }); - - describe('for Edition 2.1 projects', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2007B4.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editConnectedApWizard(doc.querySelector('ConnectedAP')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - describe('contains an input to edit P element of type IPv6', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'IPv6'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV6(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv6), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IPv6-SUBNET', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'IPv6-SUBNET'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV6SubNet(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9/]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IPv6-GATEWAY', () => { - beforeEach(async () => { - input = inputs.find(input => input.label === 'IPv6-GATEWAY'); - if (input && (input).maybeValue === null) { - await (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV6(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv6), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IPv6FlowLabel', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IPv6FlowLabel'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - fc.hexaString({ minLength: 1, maxLength: 5 }), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty( - invertedRegex(/^[0-9a-fA-F]{1,5}$/), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - } - ) - )); - }); - - describe('contains an input to edit P element of type IPv6ClassOfTraffic', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IPv6ClassOfTraffic'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - nat({ max: 255 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(/^[0-9]*$/), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IPv6-IGMPv3Src', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IPv6-IGMPv3Src'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV6(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv6), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IP-IGMPv3Sr', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IP-IGMPv3Sr'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(ipV4(), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.IPv4), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type IP-ClassOfTraffic', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'IP-ClassOfTraffic'); - if (input && (input).maybeValue === null) { - (input).nullSwitch?.click(); - } - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(regexString(regExp.OSI, 1, 2), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.OSI), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/connectedap.test.ts b/packages/plugins/test/unit/wizards/connectedap.test.ts deleted file mode 100644 index a0f7086881..0000000000 --- a/packages/plugins/test/unit/wizards/connectedap.test.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { Checkbox } from '@material/mwc-checkbox'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isSimple, - ComplexAction, - Delete, - Create -} from '@openscd/core/foundation/deprecated/editor.js'; -import { editConnectedApWizard } from '../../../src/wizards/connectedap.js'; - -describe('Wizards for SCL element ConnectedAP', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editConnectedApWizard(doc.querySelector('ConnectedAP')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not edit any P element with unchanged wizard inputs', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers a complex editor action to update P elements(s)', async () => { - input = inputs.find(input => input.label === 'IP'); - input.value = '192.168.210.158'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.not.satisfy(isSimple); - }); - - it('triggers a complex action as combination of delete and create with prior existing Address field', async () => { - input = inputs.find(input => input.label === 'IP'); - input.value = '192.168.210.158'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - expect(complexAction.actions).to.have.lengthOf(2); - expect(complexAction.actions[0]).to.satisfy(isDelete); - expect(complexAction.actions[1]).to.satisfy(isCreate); - }); - - it('triggers a complex action being a pure create with prior missing Address field', async () => { - doc - .querySelector('ConnectedAP') - ?.removeChild(doc.querySelector('ConnectedAP > Address')!); - - input = inputs.find(input => input.label === 'IP'); - input.value = '192.168.210.158'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - expect(complexAction.actions).to.have.lengthOf(1); - expect(complexAction.actions[0]).to.satisfy(isCreate); - }); - - it('properly updates a P element of type IP', async () => { - input = inputs.find(input => input.label === 'IP'); - input.value = '192.168.210.158'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - expect( - oldAddress.querySelector('P[type="IP"]')?.textContent - ).to.equal('192.168.210.111'); - expect( - newAddress.querySelector('P[type="IP"]')?.textContent - ).to.equal('192.168.210.158'); - }); - - it('adds type restrictions with selected option type restriction', async () => { - (( - element.wizardUI.shadowRoot?.querySelector('#typeRestriction') - )).checked = true; - await element.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - const oldIP = oldAddress.querySelector('P[type="IP"]'); - const newIP = newAddress.querySelector('P[type="IP"]'); - - expect( - oldIP?.getAttributeNS( - 'http://www.w3.org/2001/XMLSchema-instance', - 'type' - ) - ).to.not.exist; - expect( - newIP?.getAttributeNS( - 'http://www.w3.org/2001/XMLSchema-instance', - 'type' - ) - ).to.exist; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/connectivitynode.test.ts b/packages/plugins/test/unit/wizards/connectivitynode.test.ts deleted file mode 100644 index e2d8af677e..0000000000 --- a/packages/plugins/test/unit/wizards/connectivitynode.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { editConnectivityNodeWizard } from '../../../src/wizards/connectivitynode.js'; - -describe('Wizards for SCL element ConnectivityNode', () => { - let doc: XMLDocument; - let element: OscdWizards; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/valid2007B4withSubstationXY.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editConnectivityNodeWizard( - doc.querySelector('ConnectivityNode')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); -}); diff --git a/packages/plugins/test/unit/wizards/controlwithiedname.test.ts b/packages/plugins/test/unit/wizards/controlwithiedname.test.ts deleted file mode 100644 index 2e2b22dbb8..0000000000 --- a/packages/plugins/test/unit/wizards/controlwithiedname.test.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import '../../../src/editors/substation/zeroline-pane.js'; -import { List } from '@material/mwc-list'; -import { ZerolinePane } from '../../../src/editors/substation/zeroline-pane.js'; - -describe('selectExtRefWizard', () => { - let doc: Document; - let parent: MockWizardEditor; - let element: ZerolinePane; - let commMappings: List; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/comm-map.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - parent = await fixture( - html`` - ); - - element = parent.querySelector('zeroline-pane')!; - await element.updateComplete; - - element.commmap.click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - commMappings = parent.wizardUI.dialog?.querySelector('filtered-list'); - }); - - it('looks like the latest snapshot', async () => { - commMappings.items[3].click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); - - it('shows all ExtRefs', async () => { - commMappings.items[3].click(); - await parent.updateComplete; - await parent.wizardUI.updateComplete; - - expect( - parent.wizardUI.dialog?.querySelectorAll('mwc-check-list-item').length - ).to.equal(14); - }); - - it('removes selected ExtRefs in case no intAddr is present', async () => { - expect( - doc.querySelector( - ':root > IED[name="IED2"] ExtRef[iedName="IED1"][ldInst="Disconnectors"][lnClass="XSWI"][doName="Pos"][daName="stVal"]' - ) - ).to.exist; - commMappings.items[3].click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[2].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await parent.updateComplete; - expect( - doc.querySelector( - ':root > IED[name="IED2"] ExtREf[iedName="IED1"][ldInst="Disconnectors"][lnClass="XSWI"][doName="Pos"][daName="stVal"]' - ) - ).to.not.exist; - }); - - it('updates selected ExtRefs in case intAddr is present', async () => { - expect( - doc.querySelector( - ':root > IED[name="IED1"] ExtRef[iedName="IED2"][ldInst="CBSW"][lnClass="XSWI"]' + - '[doName="Pos"][daName="stVal"][intAddr="./stVal"][serviceType="GOOSE"][desc="testDesc"]' + - '[pServT="GOOSE"][pLN="XSWI"][pDO="Pos"][pDA="stVal"]' - ) - ).to.exist; - commMappings.items[4].click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[0].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await parent.updateComplete; - expect( - doc.querySelector( - ':root > IED[name="IED1"] ExtRef:not([iedName]):not([ldInst]):not([lnClass]):not([doName]):not([daName])' + - '[intAddr="./stVal"][serviceType="GOOSE"][desc="testDesc"]' + - '[pServT="GOOSE"][pLN="XSWI"][pDO="Pos"][pDA="stVal"]' - ) - ).to.exist; - }); - it('removes IEDName if all linked ExtRefs are removed/disconnected', async () => { - expect( - doc.querySelector( - ':root > IED[name="IED1"] > AccessPoint > Server > ' + - 'LDevice[inst="CircuitBreaker_CB1"] > LN0 > GSEControl > ' + - 'IEDName[apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"]' - ) - ).to.exist; - commMappings.items[5].click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[0].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[1].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[2].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[3].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await parent.updateComplete; - expect( - doc.querySelector( - ':root > IED[name="IED1"] > AccessPoint > Server > ' + - 'LDevice[inst="CircuitBreaker_CB1"] > LN0 > GSEControl > ' + - 'IEDName[apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"]' - ) - ).to.not.exist; - }); - it('does not removes IEDName if linked ExtRefs`not completely removed/disconnected', async () => { - expect( - doc.querySelector( - ':root > IED[name="IED1"] > AccessPoint > Server > ' + - 'LDevice[inst="CircuitBreaker_CB1"] > LN0 > GSEControl > ' + - 'IEDName[apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"]' - ) - ).to.exist; - commMappings.items[5].click(); - await parent.updateComplete; - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[0].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('filtered-list') - )).items[1].click(); - await parent.updateComplete; - (( - parent.wizardUI.dialog?.querySelector('mwc-button[slot="primaryAction"]') - )).click(); - await parent.updateComplete; - expect( - doc.querySelector( - ':root > IED[name="IED1"] > AccessPoint > Server > ' + - 'LDevice[inst="CircuitBreaker_CB1"] > LN0 > GSEControl > ' + - 'IEDName[apRef="P1"][ldInst="CircuitBreaker_CB1"][lnClass="CSWI"]' - ) - ).to.exist; - }); -}); diff --git a/packages/plugins/test/unit/wizards/da.test.ts b/packages/plugins/test/unit/wizards/da.test.ts deleted file mode 100644 index b3b1efb6f9..0000000000 --- a/packages/plugins/test/unit/wizards/da.test.ts +++ /dev/null @@ -1,376 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { wizardContent } from '../../../src/wizards/abstractda.js'; -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createDaAction, - renderDa, - updateDaAction, -} from '../../../src/wizards/da.js'; - -describe('da wizards', () => { - describe('updateDaAction', () => { - let doc: XMLDocument; - let data: Element; - let element: OscdWizards; - - const da = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/abstractda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - data = doc.querySelector('DataTypeTemplates')!; - const types = Array.from(data.querySelectorAll('DAType,EnumType')); - wizard = [ - { - title: 'title', - content: [ - ...wizardContent( - 'ctlModel', - null, - 'Enum', - types, - 'Dummy_ctlModel', - null, - null, - null, - null, - data - ), - ...renderDa('CF', null, null, null), - ], - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('does not update a DA element when no attribute nor Val has changed', () => { - const editorAction = updateDaAction(da); - expect(editorAction(inputs, newWizard())).to.be.empty; - }); - it('update a DA element when only name attribute changed', async () => { - inputs[0].value = 'myOrName'; - await (inputs[0]).requestUpdate(); - const editorAction = updateDaAction(da); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a DA element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a DA element when only bType attribute changed', async () => { - inputs[2].value = 'BOOLEAN'; - await (inputs[2]).requestUpdate(); - const editorAction = updateDaAction(da); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - }); - it('update a DA element when type attribute changed to null', async () => { - inputs[2].value = 'BOOLEAN'; - await (inputs[2]).requestUpdate(); - const editorAction = updateDaAction(da); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isReplace); - const updateAction = editorAction(inputs, newWizard())[0]; - expect(updateAction.old.element).to.have.attribute('type'); - expect(updateAction.new.element).to.not.have.attribute('type'); - }); - it('update a DA element when sAddr attribute changed', async () => { - const input = inputs[4]; - input.nullSwitch?.click(); - input.value = 'mysAddr'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('sAddr'); - expect(updateAction.new.element).to.have.attribute('sAddr', 'mysAddr'); - }); - it('update a DA element when valKind attribute changed', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - input.value = 'RO'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('valKind'); - expect(updateAction.new.element).to.have.attribute('valKind', 'RO'); - }); - it('update a DA element when valImport attribute changed', async () => { - const input = inputs[6]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('valImport'); - expect(updateAction.new.element).to.have.attribute('valImport', 'true'); - }); - it('creates a Val child Val attribute changes from null to something', async () => { - const input = inputs[7]; - input.nullSwitch?.click(); - input.value = 'direct-with-normal-security'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isCreate); - const updateAction = updateActions[0]; - expect( - (updateAction.new.element) - .querySelector('Val') - ?.textContent?.trim() - ).to.not.equal('direct-with-normal-security'); - }); - it('update a DA element when fc attribute changed', async () => { - const input = inputs[9]; - input.value = 'ST'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.have.attribute('fc', 'CF'); - expect(updateAction.new.element).to.have.attribute('fc', 'ST'); - }); - it('update a DA element when dchg attribute changed', async () => { - const input = inputs[10]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('dchg'); - expect(updateAction.new.element).to.have.attribute('dchg', 'true'); - }); - it('update a DA element when qchg attribute changed', async () => { - const input = inputs[11]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('qchg'); - expect(updateAction.new.element).to.have.attribute('qchg', 'true'); - }); - it('update a DA element when dupd attribute changed', async () => { - const input = inputs[12]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateDaAction(da); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('dupd'); - expect(updateAction.new.element).to.have.attribute('dupd', 'true'); - }); - }); - - describe('createDaAction', () => { - let doc: XMLDocument; - let data: Element; - let element: OscdWizards; - - const daType = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/abstractda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - data = doc.querySelector('DataTypeTemplates')!; - const types = Array.from(data.querySelectorAll('DAType,EnumType')); - wizard = [ - { - title: 'title', - content: [ - ...wizardContent( - 'sboTimeout', - null, - 'INT32', - types, - null, - null, - null, - null, - null, - data - ), - ...renderDa('CF', null, null, null), - ], - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('creates a DA element', () => { - const editorAction = createDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect(createAction.new.element).to.have.attribute('name', 'sboTimeout'); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.have.attribute('bType', 'INT32'); - expect(createAction.new.element).to.not.have.attribute('type'); - expect(createAction.new.element).to.not.have.attribute('sAddrs'); - expect(createAction.new.element).to.not.have.attribute('valKind'); - expect(createAction.new.element).to.not.have.attribute('valImport'); - expect(createAction.new.element).to.have.attribute('fc', 'CF'); - expect(createAction.new.element).to.not.have.attribute('dchg'); - expect(createAction.new.element).to.not.have.attribute('qchg'); - expect(createAction.new.element).to.not.have.attribute('dupd'); - }); - it('creates yet another BDA element with different attribute setting', async () => { - const desc = inputs[1]; - const bType = inputs[2]; - const sAddr = inputs[4]; - const valKind = inputs[5]; - const valImport = inputs[6]; - const dchg = inputs[10]; - const qchg = inputs[11]; - const dupd = inputs[12]; - - desc.nullSwitch?.click(); - desc.value = 'myDesc'; - await desc.requestUpdate(); - bType.value = 'Struct'; - await bType.requestUpdate(); - sAddr.nullSwitch?.click(); - sAddr.value = 'mysAddr'; - await sAddr.requestUpdate(); - valKind.nullSwitch?.click(); - valKind.value = 'Conf'; - await valKind.requestUpdate(); - valImport.nullSwitch?.click(); - valImport.value = 'false'; - await valImport.requestUpdate(); - dchg.nullSwitch?.click(); - dchg.maybeValue = 'true'; - await dchg.requestUpdate(); - qchg.nullSwitch?.click(); - qchg.maybeValue = 'false'; - await qchg.requestUpdate(); - dupd.nullSwitch?.click(); - dupd.maybeValue = 'true'; - await dupd.requestUpdate(); - - const editorAction = createDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect(createAction.new.element).to.have.attribute('name', 'sboTimeout'); - expect(createAction.new.element).to.have.attribute('desc', 'myDesc'); - expect(createAction.new.element).to.have.attribute('bType', 'Struct'); - expect(createAction.new.element).to.have.attribute( - 'type', - 'AnalogueValue_i' - ); - expect(createAction.new.element).to.have.attribute('sAddr', 'mysAddr'); - expect(createAction.new.element).to.have.attribute('valKind', 'Conf'); - expect(createAction.new.element).to.have.attribute('valImport', 'false'); - expect(createAction.new.element).to.have.attribute('dchg', 'true'); - expect(createAction.new.element).to.have.attribute('qchg', 'false'); - expect(createAction.new.element).to.have.attribute('dupd', 'true'); - }); - it('creates Val childelement when checked', async () => { - const Val = inputs[8]; - - Val.nullSwitch?.click(); - Val.value = '8123'; - await Val.requestUpdate(); - - const editorAction = createDaAction(daType); - expect(editorAction(inputs, newWizard()).length).to.equal(1); - expect(editorAction(inputs, newWizard())[0]).to.satisfy(isCreate); - const createAction = editorAction(inputs, newWizard())[0]; - expect( - (createAction.new.element) - .querySelector('Val') - ?.textContent?.trim() - ).to.equal('8123'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/dai.test.ts b/packages/plugins/test/unit/wizards/dai.test.ts deleted file mode 100644 index 417e1baf99..0000000000 --- a/packages/plugins/test/unit/wizards/dai.test.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardAction, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isSimple, - Create, - Replace, - ComplexAction -} from '@openscd/core/foundation/deprecated/editor.js'; - -import { fetchDoc, setWizardTextFieldValue } from './test-support.js'; -import { - createDAIWizard, - createValue, - editDAIWizard, - updateValue, -} from '../../../src/wizards/dai.js'; - -describe('Wizards for SCL element DAI', () => { - let doc: XMLDocument; - let doi: Element; - let dai: Element; - let da: Element; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - describe('create DAI with existing Val Element', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - dai = doc.querySelector( - 'IED[name="IED1"] > AccessPoint[name="P1"] > Server > LDevice[inst="CircuitBreaker_CB1"] > LN[inst="1"][lnClass="XCBR"] > DOI[name="Beh"] > DAI[name="integer"]' - )!; - doi = dai.closest('DOI')!; - da = doc.querySelector( - 'DOType[cdc="ENS"][id="Dummy.LLN0.Beh"] > DA[name="integer"]' - )!; - - element = await fixture( - html`` - ); - const wizard = createDAIWizard(doi, dai, da); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update value should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], '24'); - - const complexActions = createValue( - doi, - da, - dai, - dai - )(inputs, element.wizardUI); - expectCreateComplexAction(complexActions, '24'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('create DAI without Val Element', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - dai = doc.querySelector( - 'IED[name="IED1"] > AccessPoint[name="P1"] > Server > LDevice[inst="CircuitBreaker_CB1"] > LN[inst="1"][lnClass="XCBR"] > DOI[name="Beh"] > DAI[name="t"]' - )!; - doi = dai.closest('DOI')!; - da = doc.querySelector( - 'DOType[cdc="ENS"][id="Dummy.LLN0.Beh"] > DA[name="t"]' - )!; - - element = await fixture( - html`` - ); - const wizard = createDAIWizard(doi, dai, da); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update value should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], ''); - await setWizardTextFieldValue(inputs[1], ''); - - const complexActions = createValue( - doi, - da, - dai, - dai - )(inputs, element.wizardUI); - expectCreateComplexAction(complexActions, '0000-00-00T00:00:00.000'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('edit existing DAI with Val Element', () => { - describe('having on value', () => { - let val: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - dai = doc.querySelector( - 'IED[name="IED1"] > AccessPoint[name="P1"] > Server > LDevice[inst="CircuitBreaker_CB1"] > LN[prefix="CB"][lnClass="CSWI"] > DOI[name="Beh"] > DAI[name="integer"]' - )!; - val = dai.querySelector('Val')!; - da = doc.querySelector( - 'DOType[cdc="ENS"][id="Dummy.LLN0.Beh"] > DA[name="integer"]' - )!; - - element = await fixture( - html`` - ); - const wizard = editDAIWizard(da, dai); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update value should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], '8'); - - const complexActions = updateValue(da, val)(inputs, element.wizardUI); - expectUpdateComplexAction(complexActions); - - const replace = (complexActions[0]).actions[0]; - expect(replace.old.element.textContent).to.equal('5'); - expect(replace.new.element.textContent).to.equal('8'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('having multiple setting group values', () => { - let val: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/settingGroups.scd'); - dai = doc.querySelector( - ':root > IED[name="IED1"] > AccessPoint[name="AP1"] > Server > ' + - 'LDevice[inst="stage2"] > LN[lnType="OpenSCD_PTOC"] > DOI[name="StrVal"] > SDI[name="setMag"] > DAI[name="f"]' - )!; - val = dai.querySelectorAll('Val')[1]; - da = doc.querySelector( - 'DAType[id="OpenSCD_AnVal_FLOAT32"] > BDA[name="f"]' - )!; - - element = await fixture( - html`` - ); - const wizard = editDAIWizard(da, dai); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update value should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], '800'); - - const complexActions = updateValue(da, val)(inputs, element.wizardUI); - expectUpdateComplexAction(complexActions); - - const replace = (complexActions[0]).actions[0]; - expect(replace.old.element.textContent).to.equal('600'); - expect(replace.new.element.textContent).to.equal('800'); - }); - }); - }); - - function expectUpdateComplexAction(complexActions: WizardAction[]): void { - expect(complexActions.length).to.equal(1); - expect(complexActions[0]).to.not.satisfy(isSimple); - - expect((complexActions[0]).title).to.equal( - '[dai.action.updatedai]' - ); - - const actions = (complexActions[0]).actions; - expect(actions.length).to.equal(1); - } - - function expectCreateComplexAction( - complexActions: WizardAction[], - expectedValue: string - ): void { - expect(complexActions.length).to.equal(1); - expect(complexActions[0]).to.not.satisfy(isSimple); - - expect((complexActions[0]).title).to.equal( - '[dai.action.createdai]' - ); - - const actions = (complexActions[0]).actions; - expect(actions.length).to.equal(1); - - const create = actions[0]; - expect(create.new.parent).to.equal(doi); - expect(create.new.element).to.equal(dai); - - const val = dai.querySelector('Val')!; - expect(val.textContent).to.be.equal(expectedValue); - } -}); diff --git a/packages/plugins/test/unit/wizards/dataset.test.ts b/packages/plugins/test/unit/wizards/dataset.test.ts deleted file mode 100644 index 52ac5e44ab..0000000000 --- a/packages/plugins/test/unit/wizards/dataset.test.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import { editDataSetWizard } from '../../../src/wizards/dataset.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isDelete, - isReplace, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; - -describe('dataset wizards', () => { - let doc: XMLDocument; - let element: OscdWizards; - let wizardEvent: SinonSpy; - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/gsecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('include a dataset edit wizard', () => { - beforeEach(async () => { - const wizard = editDataSetWizard( - doc.querySelector('IED[name="IED2"] DataSet[name="GooseDataSet1"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - wizardEvent = spy(); - window.addEventListener('wizard', wizardEvent); - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()).timeout(5000); - - it('allows to add a new FCDA on add FCDA button click', async () => { - const addButton = ( - Array.from( - element.wizardUI.dialog!.querySelectorAll( - 'mwc-menu > mwc-list-item' - ) - ).find(item => item.innerHTML.includes('dataset.fcda.add')) - ); - await addButton.click(); - expect(wizardEvent).to.be.calledOnce; - }); - - describe('with stand alone DataSet', () => { - let dataSet: Element; - let wizard: Wizard; - let inputs: WizardInputElement[]; - let primaryAction: HTMLElement; - - beforeEach(async () => { - dataSet = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - wizard = editDataSetWizard(dataSet); - element.workflow.length = 0; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('does not update a DataSet element when no attribute has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update a DataSet element when only name attribute changed', async () => { - const input = inputs[0]; - input.value = 'myNewDataSetName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('name', 'myDS'); - expect(updateAction.new.element).to.have.attribute( - 'name', - 'myNewDataSetName' - ); - }); - }); - - describe('with connected DataSet', () => { - let dataSet: Element; - let wizard: Wizard; - let inputs: WizardInputElement[]; - let primaryAction: HTMLElement; - let firstFCDA: HTMLElement; - let thirdFCDA: HTMLElement; - - beforeEach(async () => { - dataSet = doc.querySelector( - 'IED[name="IED2"] DataSet[name="GooseDataSet1"]' - )!; - wizard = editDataSetWizard(dataSet); - element.workflow.length = 0; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - firstFCDA = ( - element.wizardUI.dialog?.querySelector( - 'filtered-list>mwc-check-list-item' - ) - ); - - thirdFCDA = ( - element.wizardUI.dialog?.querySelector( - 'filtered-list>mwc-check-list-item:nth-child(3)' - ) - ); - }); - - it('does not update a DataSet element when no attribute has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update a DataSet element when only name attribute changed', async () => { - const input = inputs[0]; - input.value = 'myNewDataSetName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledThrice; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute( - 'name', - 'GooseDataSet1' - ); - expect(updateAction.new.element).to.have.attribute( - 'name', - 'myNewDataSetName' - ); - }); - - it('update a DataSet of all referenced control blocks', async () => { - const input = inputs[0]; - input.value = 'myNewDataSetName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledThrice; - - for (let i = 1; i < actionEvent.args.length; i++) { - const action = actionEvent.args[i][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute( - 'datSet', - 'GooseDataSet1' - ); - expect(updateAction.new.element).to.have.attribute( - 'datSet', - 'myNewDataSetName' - ); - } - }); - - it('update a DataSet element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('desc'); - expect(updateAction.new.element).to.have.attribute('desc', 'myDesc'); - }); - - it('removes all unselected FCDA child elements', async () => { - firstFCDA.click(); - thirdFCDA.click(); - await element.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledTwice; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isDelete); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('ldInst', 'CBSW'); - expect(updateAction.old.element).to.have.attribute('prefix', ''); - expect(updateAction.old.element).to.have.attribute('lnClass', 'XSWI'); - expect(updateAction.old.element).to.have.attribute('lnInst', '2'); - expect(updateAction.old.element).to.have.attribute('doName', 'Pos'); - expect(updateAction.old.element).to.have.attribute('daName', 'stVal'); - }); - - it('removes all unselected FCDA child elements', async () => { - firstFCDA.click(); - thirdFCDA.click(); - await element.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledTwice; - - const action = actionEvent.args[1][0].detail.action; - expect(action).to.satisfy(isDelete); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('ldInst', 'CBSW'); - expect(updateAction.old.element).to.have.attribute('prefix', ''); - expect(updateAction.old.element).to.have.attribute('lnClass', 'XSWI'); - expect(updateAction.old.element).to.have.attribute('lnInst', '2'); - expect(updateAction.old.element).to.have.attribute( - 'doName', - 'OpSlc.dsd' - ); - expect(updateAction.old.element).to.have.attribute( - 'daName', - 'sasd.ads.asd' - ); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/eqfunction.test.ts b/packages/plugins/test/unit/wizards/eqfunction.test.ts deleted file mode 100644 index bdbecbd2dd..0000000000 --- a/packages/plugins/test/unit/wizards/eqfunction.test.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createEqFunctionWizard, - editEqFunctionWizard, -} from '../../../src/wizards/eqfunction.js'; - -describe('Wizards for SCL EqFunction element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createEqFunctionWizard( - doc.querySelector('ConductingEquipment')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple create action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.not.have.attribute('type'); - }); - - it('allows to create non required attributes desc and type', async () => { - inputs[0].value = 'someNonEmptyName'; - - (inputs[1]).nullSwitch?.click(); - (inputs[2]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - inputs[2].value = 'SomeType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'SomeType'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editEqFunctionWizard( - doc.querySelector( - 'PowerTransformer[name="myPtr3"] > EqFunction[name="myEqFuncQB3"]' - )! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action without changes', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action if name attribute is not unique', async () => { - inputs[0].value = 'myEqFuncQB2'; - primaryAction.click(); - await element.updateComplete; - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple replace action updating name attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('triggers simple replace action updating desc attribute', async () => { - inputs[1].value = 'someDesc'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - - it('triggers simple replace action updating type attribute', async () => { - inputs[2].value = 'someType'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('type', 'someType'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/eqsubfunction.test.ts b/packages/plugins/test/unit/wizards/eqsubfunction.test.ts deleted file mode 100644 index c0763613ef..0000000000 --- a/packages/plugins/test/unit/wizards/eqsubfunction.test.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createEqSubFunctionWizard, - editEqSubFunctionWizard, -} from '../../../src/wizards/eqsubfunction.js'; - -describe('Wizards for SCL EqSubFunction element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createEqSubFunctionWizard( - doc.querySelector('EqFunction')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple create action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.not.have.attribute('type'); - }); - - it('allows to create non required attributes desc and type', async () => { - inputs[0].value = 'someNonEmptyName'; - - (inputs[1]).nullSwitch?.click(); - (inputs[2]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - inputs[2].value = 'SomeType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'SomeType'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editEqSubFunctionWizard( - doc.querySelector( - 'ConductingEquipment[name="QA1"] EqSubFunction[name="myEqSubSubFunction"]' - )! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action without changes', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action if name attribute is not unique', async () => { - inputs[0].value = 'myEqFunc2'; - primaryAction.click(); - await element.updateComplete; - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple replace action updating name attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('triggers simple replace action updating desc attribute', async () => { - inputs[1].value = 'someDesc'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - - it('triggers simple replace action updating type attribute', async () => { - inputs[2].value = 'someType'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('type', 'someType'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/fcda.test.ts b/packages/plugins/test/unit/wizards/fcda.test.ts deleted file mode 100644 index f7a0ee1c49..0000000000 --- a/packages/plugins/test/unit/wizards/fcda.test.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { createFCDAsWizard } from '../../../src/wizards/fcda.js'; -import { isCreate } from '@openscd/core/foundation/deprecated/editor.js'; -import { FinderList } from '@openscd/open-scd/src/finder-list.js'; - -describe('create wizard for FCDA element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let finder: FinderList; - let primaryAction: HTMLElement; - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/fcda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('with a valid SCL file', () => { - beforeEach(async () => { - const wizard = createFCDAsWizard(doc.querySelector('DataSet')!); - element.workflow.push(() => wizard!); - await element.requestUpdate(); - finder = - element.wizardUI.dialog!.querySelector('finder-list')!; - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the last snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }); - - it('indicates error in case children cannot be determined', async () => { - finder.paths = [['some wrong path']]; - await element.requestUpdate(); - await finder.loaded; - expect( - element.wizardUI.dialog - ?.querySelector('finder-list') - ?.shadowRoot?.querySelector('p')?.innerText - ).to.equal('[error]'); - }); - - describe('with a specific path', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>CircuitBreaker_CB1', - 'LN0: IED1>>CircuitBreaker_CB1', - 'DO: #Dummy.LLN0>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('returns a non empty create action on primary action click', () => { - expect(actionEvent).to.have.been.called; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - }); - - it('returns a create action that follows the definition of a FCDA', () => { - const newElement = ( - actionEvent.args[0][0].detail.action.new.element - ); - expect(newElement).to.have.attribute('ldInst', 'CircuitBreaker_CB1'); - expect(newElement).to.have.attribute('prefix', ''); - expect(newElement).to.have.attribute('lnClass', 'LLN0'); - expect(newElement).to.not.have.attribute('lnInst'); - expect(newElement).to.have.attribute('doName', 'Beh'); - expect(newElement).to.have.attribute('daName', 'stVal'); - expect(newElement).to.have.attribute('fc', 'ST'); - }); - }); - - describe('with a more complex path including SDOs and BDAs', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>Meas', - 'LN: IED1>>Meas>My MMXU 1', - 'DO: #Dummy.MMXU>A', - 'SDO: #OpenSCD_WYE_phases>phsA', - 'DA: #OpenSCD_CMV_db_i_MagAndAng>cVal', - 'BDA: #OpenSCD_Vector_I_w_Ang>mag', - 'BDA: #OpenSCD_AnalogueValue_INT32>i', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('returns a non empty create action on primary action click', () => { - expect(actionEvent).to.have.been.called; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - }); - - it('returns a create action that follows the definition of a FCDA', () => { - const newElement = ( - actionEvent.args[0][0].detail.action.new.element - ); - expect(newElement).to.have.attribute('ldInst', 'Meas'); - expect(newElement).to.have.attribute('prefix', 'My'); - expect(newElement).to.have.attribute('lnClass', 'MMXU'); - expect(newElement).to.have.attribute('lnInst', '1'); - expect(newElement).to.have.attribute('doName', 'A.phsA'); - expect(newElement).to.have.attribute('daName', 'cVal.mag.i'); - expect(newElement).to.have.attribute('fc', 'MX'); - }); - }); - - describe('with path being non leaf node', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>Meas', - 'LN: IED1>>Meas>My MMXU 1', - 'DO: #Dummy.MMXU>A', - 'SDO: #OpenSCD_WYE_phases>phsA', - 'DA: #OpenSCD_CMV_db_i_MagAndAng>cVal', - 'BDA: #OpenSCD_Vector_I_w_Ang>mag', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('returns a non empty create action on primary action click', () => - expect(actionEvent).to.not.have.been.called); - }); - - describe('with a incorrect logical node definition in the path', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>Meas', - 'Ln: IED1>>Meas>My MMXU 1', - 'DO: #Dummy.LLN0>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('does not return a empty action on primary action click', () => - expect(actionEvent).to.not.have.been.called); - }); - - describe('with a incorrect logical node identity in the path', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>CircuitBreaker_CB1', - 'LN0: some wrong identity', - 'DO: #Dummy.LLN0>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('does not return a empty action on primary action click', () => - expect(actionEvent).to.not.have.been.called); - }); - - describe('with a incorrect DO definition in the path', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>CircuitBreaker_CB1', - 'LN0: IED1>>CircuitBreaker_CB1', - 'DO: some wrong identity', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('does not return a empty action on primary action click', () => - expect(actionEvent).to.not.have.been.called); - }); - - describe('with a missing fc definition in the DA in the SCL file', () => { - const path = [ - 'Server: IED1>P1', - 'LDevice: IED1>>CircuitBreaker_CB1', - 'LN: IED1>>CircuitBreaker_CB1> XCBR 1', - 'DO: #Dummy.XCBR1>Pos', - 'DA: #Dummy.XCBR1.Pos>stVal', - ]; - - beforeEach(async () => { - finder.paths = [path]; - await element.requestUpdate(); - await primaryAction.click(); - }); - - it('does not return a empty action on primary action click', () => - expect(actionEvent).to.not.have.been.called); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/foundation/__snapshots__/dai-field-type.test.snap.js b/packages/plugins/test/unit/wizards/foundation/__snapshots__/dai-field-type.test.snap.js deleted file mode 100644 index 125ff1536f..0000000000 --- a/packages/plugins/test/unit/wizards/foundation/__snapshots__/dai-field-type.test.snap.js +++ /dev/null @@ -1,634 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["dai-field-type getCustomField BOOLEAN field render function returns the correct snapshot"] = -` -
    - - - true - - - false - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField BOOLEAN field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField ENUM field render function returns the correct snapshot"] = -` -
    - - - on - - - blocked - - - test - - - test/blocked - - - off - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField ENUM field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField FLOAT32 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField FLOAT32 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField FLOAT64 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField FLOAT64 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT8 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT8 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT16 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT16 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT24 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT24 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT32 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT32 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT64 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT64 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT128 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT128 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT8U field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT8U field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT16U field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT16U field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT24U field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT24U field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField INT32U field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField INT32U field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField Timestamp field render function returns the correct snapshot"] = -` -
    - - - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField Timestamp field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField VisString32 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField VisString32 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField VisString64 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField VisString64 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField VisString65 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField VisString65 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField VisString129 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField VisString129 field render function returns the correct snapshot */ - -snapshots["dai-field-type getCustomField VisString255 field render function returns the correct snapshot"] = -` -
    - - -
    - - -
    -`; -/* end snapshot dai-field-type getCustomField VisString255 field render function returns the correct snapshot */ - diff --git a/packages/plugins/test/unit/wizards/foundation/dai-field-type.test.ts b/packages/plugins/test/unit/wizards/foundation/dai-field-type.test.ts deleted file mode 100644 index e309df9ae9..0000000000 --- a/packages/plugins/test/unit/wizards/foundation/dai-field-type.test.ts +++ /dev/null @@ -1,676 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { Wizard, WizardInputElement } from '@openscd/open-scd/src/foundation.js'; - -import { - CustomField, - DaiFieldTypes, - getCustomField, - getDateValueFromTimestamp, - getTimeValueFromTimestamp, -} from '../../../../src/wizards/foundation/dai-field-type.js'; - -describe('dai-field-type', async () => { - let validSCL: XMLDocument; - - beforeEach(async () => { - validSCL = await fetch('/test/testfiles/valid2007B4ForDAIValidation.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('getCustomField', () => { - let customField: CustomField; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - function getDAElement(doType: string, doName: string): Element { - return validSCL.querySelector( - `DOType[id="${doType}"] > DA[name="${doName}"]` - )!; - } - - function getDAIElement(daiName: string): Element | null { - return validSCL.querySelector(`DAI[name="${daiName}"]`); - } - - function wizard( - customField: CustomField, - daElement: Element, - daiElement: Element | null - ): Wizard { - return [ - { - title: 'Custom Field Wizard', - content: [html`${customField.render(daElement, daiElement!)}`], - }, - ]; - } - - describe('BOOLEAN field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'booleantest'); - const daiElement = getDAIElement('booleantest'); - - customField = getCustomField()['BOOLEAN']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('true'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('true'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('ENUM field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'enumtest'); - const daiElement = getDAIElement('enumtest'); - - customField = getCustomField()['Enum']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('blocked'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('blocked'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('FLOAT32 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'float32test'); - const daiElement = getDAIElement('float32test'); - - customField = getCustomField()['FLOAT32']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('659.3'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('659.3'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('FLOAT64 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'float64test'); - const daiElement = getDAIElement('float64test'); - - customField = getCustomField()['FLOAT64']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('1111659.8'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('1111659.8'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT8 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int8test'); - const daiElement = getDAIElement('int8test'); - - customField = getCustomField()['INT8']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('5'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('5'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT16 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int16test'); - const daiElement = getDAIElement('int16test'); - - customField = getCustomField()['INT16']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('500'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('500'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT24 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int24test'); - const daiElement = getDAIElement('int24test'); - - customField = getCustomField()['INT24']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('8321'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('8321'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT32 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int32test'); - const daiElement = getDAIElement('int32test'); - - customField = getCustomField()['INT32']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('83218'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('83218'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT64 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int64test'); - const daiElement = getDAIElement('int64test'); - - customField = getCustomField()['INT64']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('-543923'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('-543923'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT128 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int128test'); - const daiElement = getDAIElement('int128test'); - - customField = getCustomField()['INT128']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('-8'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('-8'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT8U field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int8utest'); - const daiElement = getDAIElement('int8utest'); - - customField = getCustomField()['INT8U']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('99'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('99'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT16U field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int16utest'); - const daiElement = getDAIElement('int16utest'); - - customField = getCustomField()['INT16U']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('20000'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('20000'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT24U field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int24utest'); - const daiElement = getDAIElement('int24utest'); - - customField = getCustomField()['INT24U']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('654321'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('654321'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('INT32U field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'int32utest'); - const daiElement = getDAIElement('int32utest'); - - customField = getCustomField()['INT32U']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('2'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('2'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('Timestamp field', async () => { - async function prepareTimestamp( - daElement: Element, - daiElement: Element | null - ): Promise { - customField = getCustomField()['Timestamp']; - element = await fixture( - html` ` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - } - - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'timestamptest'); - const daiElement = getDAIElement('timestamptest'); - await prepareTimestamp(daElement, daiElement); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('2022-03-24'); - expect(inputs[1].value).to.be.equal('12:34:56'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('2022-03-24T12:34:56.000'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - describe('with "null" value', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'nulltimestamptest'); - const daiElement = getDAIElement('nulltimestamptest'); - await prepareTimestamp(daElement, daiElement); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.empty; - expect(inputs[1].value).to.be.empty; - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('0000-00-00T00:00:00.000'); - }); - }); - }); - - describe('VisString32 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'visstring32test'); - const daiElement = getDAIElement('visstring32test'); - - customField = getCustomField()['VisString32']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('pull-ups'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('pull-ups'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('VisString64 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'visstring64test'); - const daiElement = getDAIElement('visstring64test'); - - customField = getCustomField()['VisString64']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('lat pulldown'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('lat pulldown'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('VisString65 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'visstring65test'); - const daiElement = getDAIElement('visstring65test'); - - customField = getCustomField()['VisString65']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('bench press'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('bench press'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('VisString129 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'visstring129test'); - const daiElement = getDAIElement('visstring129test'); - - customField = getCustomField()['VisString129']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('front squat'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('front squat'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('VisString255 field', async () => { - beforeEach(async () => { - const daElement = getDAElement('Dummy.LLN0.Beh', 'visstring255test'); - const daiElement = getDAIElement('visstring255test'); - - customField = getCustomField()['VisString255']; - element = await fixture( - html`` - ); - element.workflow.push(() => wizard(customField, daElement, daiElement)); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('input fields contain the correct values', () => { - expect(inputs[0].value).to.be.equal('deadlift'); - }); - - it('value returns the expected value', () => { - expect(customField.value(inputs)).to.eql('deadlift'); - }); - - it('render function returns the correct snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - }); - - describe('getDateValueFromTimestamp', () => { - it('when normal timestamp passed then date value is returned', () => { - const dateValue = getDateValueFromTimestamp('2022-03-24T12:34:56.000'); - expect(dateValue).to.be.equal('2022-03-24'); - }); - - it('when only date part passed then date value is returned', () => { - const dateValue = getDateValueFromTimestamp('2022-03-24'); - expect(dateValue).to.be.equal('2022-03-24'); - }); - - it('when null timestamp passed then null is returned', () => { - const dateValue = getDateValueFromTimestamp('0000-00-00T00:00:00.000'); - expect(dateValue).to.be.null; - }); - - it('when invalid timestamp passed then null is returned', () => { - const dateValue = getDateValueFromTimestamp('INVA-LI-D2T12:34:56.000'); - expect(dateValue).to.be.null; - }); - - it('when empty string passed then null is returned', () => { - const dateValue = getDateValueFromTimestamp(''); - expect(dateValue).to.be.null; - }); - }); - - describe('getTimeValueFromTimestamp', () => { - it('when normal timestamp passed then time value is returned', () => { - const dateValue = getTimeValueFromTimestamp('2022-03-24T12:34:56.000'); - expect(dateValue).to.be.equal('12:34:56'); - }); - - it('when timestamp without milliseconds passed then time value is returned', () => { - const dateValue = getTimeValueFromTimestamp('2022-03-24T12:34:56'); - expect(dateValue).to.be.equal('12:34:56'); - }); - - it('when null timestamp passed then null is returned', () => { - const dateValue = getTimeValueFromTimestamp('0000-00-00T00:00:00.000'); - expect(dateValue).to.be.null; - }); - - it('when only date part passed then null is returned', () => { - const dateValue = getTimeValueFromTimestamp('2022-03-24'); - expect(dateValue).to.be.null; - }); - - it('when invalid timestamp passed then null is returned', () => { - const dateValue = getTimeValueFromTimestamp('2022-03-24TIN:VA:LI.D00'); - expect(dateValue).to.be.null; - }); - - it('when empty string passed then null is returned', () => { - const dateValue = getTimeValueFromTimestamp(''); - expect(dateValue).to.be.null; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/foundation/finder.test.ts b/packages/plugins/test/unit/wizards/foundation/finder.test.ts deleted file mode 100644 index 9db1a086eb..0000000000 --- a/packages/plugins/test/unit/wizards/foundation/finder.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { getDataModelChildren } from '../../../../src/wizards/foundation/finder.js'; - -describe('data model nodes child getter', () => { - let doc: XMLDocument; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/wizards/fcda.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - it('returns empty array for invalid tag', () => { - const parent = doc.querySelector('IED')!; - expect(getDataModelChildren(parent)).to.be.empty; - }); - - it('returns direct children for a Server', () => { - const parent = doc.querySelector('Server')!; - expect(getDataModelChildren(parent)).to.not.be.empty; - expect(getDataModelChildren(parent)[0]).to.have.attribute( - 'inst', - 'CircuitBreaker_CB1' - ); - expect(getDataModelChildren(parent)[1]).to.have.attribute('inst', 'Meas'); - }); - - it('returns direct children for a LDevice', () => { - const parent = doc.querySelector('LDevice')!; - expect(getDataModelChildren(parent)).to.not.be.empty; - expect(getDataModelChildren(parent)[0]).to.have.attribute( - 'lnClass', - 'LLN0' - ); - expect(getDataModelChildren(parent)[1]).to.have.attribute( - 'lnClass', - 'XCBR' - ); - }); - - it('returns referenced children for LN/LN0', () => { - const parent = doc.querySelector('LN')!; - expect(getDataModelChildren(parent).length).to.equal(1); - expect(getDataModelChildren(parent)[0]).to.have.attribute('name', 'Pos'); - }); - - it('returns referenced children for DO', () => { - const parent = doc.querySelector('DO')!; - expect(getDataModelChildren(parent).length).to.equal(3); - expect(getDataModelChildren(parent)[0]).to.have.attribute('name', 'stVal'); - expect(getDataModelChildren(parent)[1]).to.have.attribute('name', 'q'); - expect(getDataModelChildren(parent)[2]).to.have.attribute('name', 't'); - }); - - it('returns referenced children for SDO', () => { - const parent = doc.querySelector('SDO')!; - expect(getDataModelChildren(parent).length).to.equal(1); - expect(getDataModelChildren(parent)[0]).to.have.attribute('name', 'cVal'); - }); - - it('returns referenced children for DA', () => { - const parent = doc.querySelector( - 'DOType[id="OpenSCD_CMV_db_i_MagAndAng"]>DA' - )!; - expect(getDataModelChildren(parent).length).to.equal(1); - expect(getDataModelChildren(parent)[0]).to.have.attribute('name', 'mag'); - }); - - it('returns referenced children for BDA', () => { - const parent = doc.querySelector( - 'DAType[id="OpenSCD_Vector_I_w_Ang"]>BDA' - )!; - expect(getDataModelChildren(parent).length).to.equal(1); - expect(getDataModelChildren(parent)[0]).to.have.attribute('name', 'i'); - }); - - it('returns empty array for leaf node', () => { - const parent = doc.querySelector('DOType[id="Dummy.XCBR1.Pos"]>DA')!; - expect(getDataModelChildren(parent)).to.be.empty; - }); -}); diff --git a/packages/plugins/test/unit/wizards/foundation/references.test.ts b/packages/plugins/test/unit/wizards/foundation/references.test.ts deleted file mode 100644 index 3f8c1f8c3a..0000000000 --- a/packages/plugins/test/unit/wizards/foundation/references.test.ts +++ /dev/null @@ -1,258 +0,0 @@ -import { - expectDeleteAction, - expectReplaceAction, - expectUpdateTextValue, - fetchDoc, -} from '../test-support.js'; -import { - deleteReferences, - updateReferences, -} from '../../../../src/wizards/foundation/references.js'; -import { expect } from '@open-wc/testing'; - -describe('Update reference for ', () => { - let doc: XMLDocument; - - describe('element without Reference Info (ConductingEquipment)', () => { - const ceName = 'QA1'; - let conductingEquipment: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - conductingEquipment = doc.querySelector( - `ConductingEquipment[name="${ceName}"]` - )!; - }); - - it('will update no references to ConductingEquipment', function () { - const updateActions = updateReferences( - conductingEquipment, - ceName, - 'Other CE Name' - ); - expect(updateActions.length).to.equal(0); - }); - - it('will delete no references to ConductingEquipment', function () { - const updateActions = deleteReferences(conductingEquipment); - expect(updateActions.length).to.equal(0); - }); - }); - - describe('element without Name Attribute (Value)', () => { - let connectAP: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - connectAP = doc.querySelector( - `ConnectedAP[iedName="IED1"][apName="P1"]` - )!; - }); - - it('will update no references to ConnectedAP', function () { - const updateActions = updateReferences(connectAP, null, 'New Name'); - expect(updateActions.length).to.equal(0); - }); - - it('will delete no references to ConnectedAP', function () { - const updateActions = deleteReferences(connectAP); - expect(updateActions.length).to.equal(0); - }); - }); - - describe('IED update Val element', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/iedRename.scd'); - }); - }); - - describe('IED', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - }); - - it('will update all references to IED IED1', function () { - const oldName = 'IED1'; - const newName = 'NewIED1'; - const ied = doc.querySelector(`IED[name="${oldName}"]`)!; - - const updateActions = updateReferences(ied, oldName, newName); - expect(updateActions.length).to.equal(9); - - expectReplaceAction( - updateActions[0], - 'Association', - 'iedName', - oldName, - newName - ); - expectReplaceAction( - updateActions[1], - 'ClientLN', - 'iedName', - oldName, - newName - ); - }); - - it('will update all references to IED IED2', function () { - const oldName = 'IED2'; - const newName = 'NewIED2'; - const ied = doc.querySelector(`IED[name="${oldName}"]`)!; - - const updateActions = updateReferences(ied, oldName, newName); - expect(updateActions.length).to.equal(8); - - expectUpdateTextValue(updateActions[6], 'GSEControl', oldName, newName); - expectUpdateTextValue( - updateActions[7], - 'SampledValueControl', - oldName, - newName - ); - }); - - it('will update all references to IED Pub and checks for correct Val elements', function () { - const oldName = 'Pub'; - const newName = 'NewPub'; - const ied = doc.querySelector(`IED[name="${oldName}"]`)!; - - const updateActions = updateReferences(ied, oldName, newName); - expect(updateActions.length).to.equal(5); - - const input1 = updateActions[0].old.element; - const input2 = updateActions[1].old.element; - const input3 = updateActions[2].old.element; - const input4 = updateActions[3].old.element; - - expect(input1.getAttribute('srcCBName')).to.be.equal(null); - expect(input2.getAttribute('srcCBName')).to.be.equal(null); - expect(input3.getAttribute('srcCBName')).to.be.equal('cb1'); - expect(input4.getAttribute('srcCBName')).to.be.equal('cb1'); - - const valSuffix3 = - input3.getAttribute('srcLDInst') + - '/' + - input3.getAttribute('srcLNClass') + - '.' + - input3.getAttribute('srcCBName'); - - expectUpdateTextValue( - updateActions[4], - 'DAI', - oldName + valSuffix3, - newName + valSuffix3 - ); - }); - - it('will delete all references to IED IED1', function () { - const name = 'IED1'; - const ied = doc.querySelector(`IED[name="${name}"]`)!; - - const updateActions = deleteReferences(ied); - expect(updateActions.length).to.equal(9); - - expectDeleteAction(updateActions[0], 'Association'); - expectDeleteAction(updateActions[1], 'ClientLN'); - }); - - it('will delete all references to IED IED2', async function () { - const name = 'IED2'; - const ied = doc.querySelector(`IED[name="${name}"]`)!; - - const updateActions = deleteReferences(ied); - expect(updateActions.length).to.equal(8); - - expectDeleteAction(updateActions[6], 'GSEControl'); - expectDeleteAction(updateActions[7], 'SampledValueControl'); - }); - }); - - describe('Substation', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/references.scd'); - }); - - it('will update all references to Substation AA1', function () { - const oldName = 'AA1'; - const newName = 'NewAA1'; - const substation = doc.querySelector(`Substation[name="${oldName}"]`)!; - - const updateActions = updateReferences(substation, oldName, newName); - expect(updateActions.length).to.equal(48); - - expectReplaceAction( - updateActions[0], - 'Terminal', - 'substationName', - oldName, - newName - ); - }); - }); - - describe('VoltageLevel', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/references.scd'); - }); - - it('will update all references to VoltageLevel "J1"', function () { - const oldName = 'J1'; - const newName = 'J1 UPD'; - const voltageLevel = doc.querySelector( - `VoltageLevel[name="${oldName}"]` - )!; - - const updateActions = updateReferences(voltageLevel, oldName, newName); - expect(updateActions.length).to.equal(48); - - expectReplaceAction( - updateActions[0], - 'Terminal', - 'voltageLevelName', - oldName, - newName - ); - }); - }); - - describe('Bay', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/references.scd'); - }); - - it('will update all references to BusBar "BusBar A"', function () { - const oldName = 'BusBar A'; - const newName = 'BusBar A UPD'; - const bay = doc.querySelector(`Bay[name="${oldName}"]`)!; - - const updateActions = updateReferences(bay, oldName, newName); - expect(updateActions.length).to.equal(6); - - expectReplaceAction( - updateActions[0], - 'Terminal', - 'bayName', - oldName, - newName - ); - }); - - it('will update all references to Bay "Bay A"', function () { - const oldName = 'Bay A'; - const newName = 'Bay A UPD'; - const bay = doc.querySelector(`Bay[name="${oldName}"]`)!; - - const updateActions = updateReferences(bay, oldName, newName); - expect(updateActions.length).to.equal(8); - - expectReplaceAction( - updateActions[0], - 'Terminal', - 'bayName', - oldName, - newName - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/foundation/scl.test.ts b/packages/plugins/test/unit/wizards/foundation/scl.test.ts deleted file mode 100644 index 968a945f8f..0000000000 --- a/packages/plugins/test/unit/wizards/foundation/scl.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { expect } from '@open-wc/testing'; -import { - uniqueAppId, - uniqueMacAddress, -} from '../../../../src/wizards/foundation/scl.js'; - -function incrementMac(oldMac: string): string { - const mac = oldMac.split('-').join(''); - //destination MAC in IEC61850 always starts with 01:0C:CD:... - const newMac = '0' + (parseInt(mac, 16) + 1).toString(16).toUpperCase(); - return newMac.match(/.{1,2}/g)!.join('-'); -} - -function createMacs(serviceType: 'SMV' | 'GOOSE'): string[] { - const maxMac = - serviceType === 'GOOSE' ? '01-0C-CD-01-01-FF' : '01-0C-CD-04-01-FF'; - const startMac = - serviceType === 'GOOSE' ? '01-0C-CD-01-00-00' : '01-0C-CD-04-00-00'; - - const macs: string[] = []; - - let mac = startMac; - while (mac !== maxMac) { - macs.push(mac); - mac = incrementMac(mac); - } - - macs.push(maxMac); - - return macs; -} - -function incrementAppId(oldAppId: string): string { - return (parseInt(oldAppId, 16) + 1) - .toString(16) - .toUpperCase() - .padStart(4, '0'); -} - -function createAppIds(): string[] { - const maxAppId = 'FFFF'; - const startAppId = '0001'; - - const appIds: string[] = []; - - let appId = startAppId; - while (appId !== maxAppId) { - appIds.push(appId); - appId = incrementAppId(appId); - } - - appIds.push(maxAppId); - - return appIds; -} - -describe('SCL specific functions', () => { - describe('define a function to get unique GSE MAC addres', () => { - describe('with all MAC address in use', () => { - const gseElementString = `${createMacs('GOOSE').map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return null with no unique MAC', () => - expect(uniqueMacAddress(doc, 'GOOSE')).to.be.null); - }); - - describe('with available MAC address', () => { - const macs = createMacs('GOOSE'); - macs.splice(4, 5); - const gseElementString = `${macs.map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return the first available first unique MAC', () => - expect(uniqueMacAddress(doc, 'GOOSE')).to.equal('01-0C-CD-01-00-04')); - }); - - describe('with one available MAC address', () => { - const macs = createMacs('GOOSE'); - macs.pop(); - const gseElementString = `${macs.map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return the first availablefirst unique MAC', () => - expect(uniqueMacAddress(doc, 'GOOSE')).to.equal('01-0C-CD-01-01-FF')); - }); - }); - - describe('define a function to get unique SMV MAC addres', () => { - describe('with all MAC address in use', () => { - const smvElementString = `${createMacs('SMV').map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - smvElementString, - 'application/xml' - ); - - it('return null with no unique MAC', () => - expect(uniqueMacAddress(doc, 'SMV')).to.be.null); - }); - - describe('with available MAC address', () => { - const macs = createMacs('SMV'); - macs.splice(10, 5); - const gseElementString = `${macs.map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return the first available unique MAC', () => - expect(uniqueMacAddress(doc, 'SMV')).to.equal('01-0C-CD-04-00-0A')); - }); - - describe('with one available MAC address', () => { - const macs = createMacs('SMV'); - macs.pop(); - const gseElementString = `${macs.map( - mac => - `

    ${mac}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return the first available unique MAC', () => - expect(uniqueMacAddress(doc, 'SMV')).to.equal('01-0C-CD-04-01-FF')); - }); - }); - - describe('define a function to get unique APPID', () => { - describe('with available APPID', () => { - const appIds = createAppIds(); - appIds.splice(10, 5); - const gseElementString = `${appIds.map( - appId => - `

    ${appId}

    ` - )}
    `; - const doc = new DOMParser().parseFromString( - gseElementString, - 'application/xml' - ); - - it('return the first available unique APPID', () => { - expect(uniqueAppId(doc)).to.equal('000B'); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/function.test.ts b/packages/plugins/test/unit/wizards/function.test.ts deleted file mode 100644 index 1be250511f..0000000000 --- a/packages/plugins/test/unit/wizards/function.test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createFunctionWizard, - editFunctionWizard, -} from '../../../src/wizards/function.js'; - -describe('Wizards for SCL Function element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createFunctionWizard(doc.querySelector('Substation')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple create action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.not.have.attribute('type'); - }); - - it('allows to create non required attributes desc and type', async () => { - inputs[0].value = 'someNonEmptyName'; - - (inputs[1]).nullSwitch?.click(); - (inputs[2]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - inputs[2].value = 'SomeType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'SomeType'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editFunctionWizard( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"]' - )! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action without changes', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action if name attribute is not unique', async () => { - inputs[0].value = 'bay2Func'; - primaryAction.click(); - await element.updateComplete; - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple replace action updating name attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('triggers simple replace action updating desc attribute', async () => { - inputs[1].value = 'someDesc'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - - it('triggers simple replace action updating type attribute', async () => { - inputs[2].value = 'someType'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('type', 'someType'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/generalequipment.test.ts b/packages/plugins/test/unit/wizards/generalequipment.test.ts deleted file mode 100644 index 925718c5de..0000000000 --- a/packages/plugins/test/unit/wizards/generalequipment.test.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createGeneralEquipmentWizard, - editGeneralEquipmentWizard, -} from '../../../src/wizards/generalEquipment.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; - -describe('Wizards for SCL GeneralEquipment element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/editors/substation/generalequipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createGeneralEquipmentWizard( - doc.querySelector('Substation')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create required attributes name and type', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'AXN'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('type', 'AXN'); - expect(createAction.new.element).to.not.have.attribute('desc'); - }); - - it('does not accept invalid type attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'notValidAXN'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create non required attributes desc', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'AXN'; - - (inputs[1]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'AXN'); - }); - - it('allows to create non required attributes virtual', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'AXN'; - - (inputs[1]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'AXN'); - expect(createAction.new.element).to.have.attribute('virtual', 'true'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editGeneralEquipmentWizard( - doc.querySelector('GeneralEquipment')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple edit action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to create non required attribute virtual', async () => { - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('virtual', 'true'); - }); - - it('does not accept empty type attribute', async () => { - inputs[2].value = ''; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - it('does not accept invalid type attribute', async () => { - inputs[2].value = 'notAXN'; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create type attribute', async () => { - inputs[2].value = 'BAT'; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('type', 'BAT'); - }); - - it('allows to create non required attribute desc', async () => { - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/gse.test.ts b/packages/plugins/test/unit/wizards/gse.test.ts deleted file mode 100644 index 11915368b8..0000000000 --- a/packages/plugins/test/unit/wizards/gse.test.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isSimple, - isReplace, - ComplexAction, - Create, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - editGseWizard, - getMTimeAction, - updateGSEAction, -} from '../../../src/wizards/gse.js'; - -describe('gse wizards', () => { - let doc: XMLDocument; - let element: OscdWizards; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/gsecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('editGseWizard', () => { - beforeEach(async () => { - const wizard = editGseWizard( - doc.querySelector('GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - }); - - describe('updateGSEAction', () => { - let gse: Element; - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - gse = doc.querySelector( - 'GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]' - )!; - wizard = editGseWizard( - doc.querySelector('GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('does not update a GSE element when no attribute has changed', () => { - const editorAction = updateGSEAction(gse); - const actions = (editorAction(inputs, element.wizardUI)[0]) - .actions; - expect(actions).to.be.empty; - }); - it('update a GSE element when only MAC-Address attribute changed', async () => { - const input = inputs[0]; - input.value = '01-0C-CD-01-00-11'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector('P[type="MAC-Address"]')?.textContent?.trim() - ).to.equal('01-0C-CD-01-00-10'); - expect( - newElement.querySelector('P[type="MAC-Address"]')?.textContent?.trim() - ).to.equal('01-0C-CD-01-00-11'); - }); - it('update a GSE element when only APPID attribute changed', async () => { - const input = inputs[1]; - input.value = '014'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector('P[type="APPID"]')?.textContent?.trim() - ).to.equal('0010'); - expect( - newElement.querySelector('P[type="APPID"]')?.textContent?.trim() - ).to.equal('014'); - }); - it('update a GSE element when only VLAN-ID attribute changed', async () => { - const input = inputs[2]; - input.maybeValue = '0F1'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect(oldElement.querySelector('P[type="VLAN-ID"]')?.textContent?.trim()) - .to.be.undefined; - expect( - newElement.querySelector('P[type="VLAN-ID"]')?.textContent?.trim() - ).to.equal('0F1'); - }); - it('update a GSE element when only VLAN-PRIORITY attribute changed', async () => { - const input = inputs[3]; - input.value = '7'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[1]).to.satisfy(isCreate); - const oldElement = (actions[0]).old.element; - const newElement = (actions[1]).new.element; - expect( - oldElement.querySelector('P[type="VLAN-PRIORITY"]')?.textContent?.trim() - ).to.equal('4'); - expect( - newElement.querySelector('P[type="VLAN-PRIORITY"]')?.textContent?.trim() - ).to.equal('7'); - }); - it('update a GSE element when only MinTime attribute changed', async () => { - const input = inputs[4]; - input.value = '15'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isReplace); - const updateAction = actions[0]; - expect(updateAction.old.element.textContent?.trim()).to.equal('10'); - expect(updateAction.new.element.textContent?.trim()).to.equal('15'); - }); - it('update a GSE element when only MaxTime attribute changed', async () => { - const input = inputs[5]; - input.value = '65'; - await input.requestUpdate(); - const editorAction = updateGSEAction(gse); - const complexAction = editorAction(inputs, newWizard()); - expect(complexAction[0]).to.not.satisfy(isSimple); - const actions = (complexAction[0]).actions; - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isReplace); - const updateAction = actions[0]; - expect(updateAction.old.element.textContent?.trim()).to.equal('10000'); - expect(updateAction.new.element.textContent?.trim()).to.equal('65'); - }); - }); - - describe('getMTimeAction', () => { - const gse = new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement; - const oldMinTime = new DOMParser().parseFromString( - `10`, - 'application/xml' - ).documentElement; - const oldMaxTime = new DOMParser().parseFromString( - `10000`, - 'application/xml' - ).documentElement; - - it('updates a MinTime child element when chenged', () => { - const editorAction = getMTimeAction('MinTime', oldMinTime, '654', gse); - expect(editorAction).to.satisfy(isReplace); - expect((editorAction).new.element.textContent?.trim()).to.equal( - '654' - ); - }); - it('creates a MimTime child element when missing', () => { - const editorAction = getMTimeAction('MinTime', null, '654', gse); - expect(editorAction).to.satisfy(isCreate); - expect((editorAction).new.element.textContent?.trim()).to.equal( - '654' - ); - }); - it('remove a Val child element if present', () => { - const editorAction = getMTimeAction('MinTime', oldMinTime, null, gse); - expect(editorAction).to.satisfy(isDelete); - }); - - it('updates a MaxTime child element when chenged', () => { - const editorAction = getMTimeAction( - 'MaxTime', - oldMaxTime, - '1234123', - gse - ); - expect(editorAction).to.satisfy(isReplace); - expect((editorAction).new.element.textContent?.trim()).to.equal( - '1234123' - ); - }); - it('creates a MaxTime child element when missing', () => { - const editorAction = getMTimeAction('MaxTime', null, '1234123', gse); - expect(editorAction).to.satisfy(isCreate); - expect((editorAction).new.element.textContent?.trim()).to.equal( - '1234123' - ); - }); - it('remove a MaxTime child element if present', () => { - const editorAction = getMTimeAction('MaxTime', oldMaxTime, null, gse); - expect(editorAction).to.satisfy(isDelete); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/gsecontrol.test.ts b/packages/plugins/test/unit/wizards/gsecontrol.test.ts deleted file mode 100644 index 24fdc13b10..0000000000 --- a/packages/plugins/test/unit/wizards/gsecontrol.test.ts +++ /dev/null @@ -1,613 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; -import fc from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - Wizard, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isReplace, - isSimple, - ComplexAction, - Create, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - contentGseControlWizard, - createGseControlWizard, - editGseControlWizard, - gseControlParentSelector, - removeGseControlAction, - selectGseControlWizard, - updateGseControlAction, -} from '../../../src/wizards/gsecontrol.js'; -import { regExp, regexString } from '../../foundation.js'; -import { FinderList } from '@openscd/open-scd/src/finder-list.js'; - -describe('gsecontrol wizards', () => { - let doc: XMLDocument; - let element: OscdWizards; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/wizards/gsecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('selectGseControlWizard', () => { - beforeEach(async () => { - const wizard = selectGseControlWizard(doc.documentElement); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - }); - - describe('renderGseAttribute', () => { - let nameTextField: WizardTextField; - - beforeEach(async () => { - const wizard = [ - { - title: 'title', - content: contentGseControlWizard({ - name: 'GSEcontrol', - desc: null, - type: 'GOOSE', - appID: 'myIED/myAP/myLD/myLN0/myGSE', - fixedOffs: null, - securityEnabled: null, - }), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - nameTextField = element.wizardUI.dialog!.querySelector( - 'wizard-textfield[label="name"]' - )!; - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - - it('edits name attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => { - nameTextField.value = name; - await nameTextField.requestUpdate(); - expect(nameTextField.checkValidity()).to.be.true; - }) - ); - }); - it('rejects name attribute starting with decimals', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => { - nameTextField.value = name; - await nameTextField.requestUpdate(); - expect(nameTextField.checkValidity()).to.be.false; - }) - ); - }); - }); - - describe('editGseControlWizard', () => { - beforeEach(async () => { - const wizard = editGseControlWizard(doc.querySelector('GSEControl')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).to.equalSnapshot(); - }).timeout(5000); - }); - - describe('removeGseControl', () => { - const ln01gse = new DOMParser().parseFromString( - ` - - - - - `, - 'application/xml' - ).documentElement; - - const ln02gse = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02rp = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02smv = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const missingparent = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - it('removes GSEControl and its refereced DataSet if no other GSEControl are aasinged', () => { - const gseControl = ln01gse.querySelector('GSEControl')!; - const actions = removeGseControlAction(gseControl)!.actions; - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(gseControl); - expect(actions[1]).to.satisfy(isDelete); - expect(actions[1].old.element).to.equal(ln01gse.querySelector('DataSet')); - }); - - it('removes GSEControl only if other GSEControl is assinged to the same DataSet', () => { - const gseControl = ln02gse.querySelector('GSEControl')!; - const actions = removeGseControlAction(gseControl)!.actions; - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(gseControl); - }); - - it('removes GSEControl only if other ReportControlBlock is assinged to the same DataSet', () => { - const gseControl = ln02rp.querySelector('GSEControl')!; - const actions = removeGseControlAction(gseControl)!.actions; - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(gseControl); - }); - - it('removes GSEControl only if other SMV is assinged to the same DataSet', () => { - const gseControl = ln02smv.querySelector('GSEControl')!; - const actions = removeGseControlAction(gseControl)!.actions; - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(gseControl); - }); - - it('does not remove with missing parent element', () => { - const action = removeGseControlAction(missingparent); - expect(action).to.be.null; - }); - - it('removes GSE element if present in the Communication section', () => { - const gseControl = doc.querySelector('IED[name="IED1"] GSEControl')!; - const actions = removeGseControlAction(gseControl)!.actions; - expect(actions.length).to.equal(3); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(gseControl); - expect(actions[1]).to.satisfy(isDelete); - expect(actions[2]).to.satisfy(isDelete); - expect(actions[2].old.element).to.equal( - doc.querySelector( - 'Communication GSE[ldInst="CircuitBreaker_CB1"][cbName="GCB"]' - ) - ); - }); - }); - - describe('updateGseControlAction', () => { - const gseControl = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - let inputs: WizardInputElement[]; - let wizard: Wizard; - - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - beforeEach(async () => { - wizard = [ - { - title: 'title', - content: contentGseControlWizard({ - name: 'myCbName', - desc: null, - type: 'GOOSE', - appID: 'myAPP/ID', - fixedOffs: null, - securityEnabled: null, - }), - }, - ]; - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - }); - - it('does not update a GSEControl element when no attribute nor Val has changed', () => { - const editorAction = updateGseControlAction(gseControl); - expect(editorAction(inputs, newWizard())).to.be.empty; - }); - it('update a GSEControl element when only name attribute changed', async () => { - const input = inputs[0]; - input.value = 'myNewCbName'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.have.attribute('name', 'myCbName'); - expect(updateAction.new.element).to.have.attribute('name', 'myNewCbName'); - }); - it('update a GSEControl element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('desc'); - expect(updateAction.new.element).to.have.attribute('desc', 'myDesc'); - }); - it('update a GSEControl element when only type attribute changed', async () => { - const input = inputs[2]; - input.value = 'GSSE'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.have.attribute('type', 'GOOSE'); - expect(updateAction.new.element).to.have.attribute('type', 'GSSE'); - }); - it('update a GSEControl element when type is changed to null', async () => { - const input = inputs[2]; - input.nullSwitch?.click(); - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.have.attribute('type', 'GOOSE'); - expect(updateAction.new.element).to.not.have.attribute('type'); - }); - it('update a GSEControl element when appID attribute changed', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.value = 'myNewType/ID'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.have.attribute('appID', 'myAPP/ID'); - expect(updateAction.new.element).to.have.attribute( - 'appID', - 'myNewType/ID' - ); - }); - it('update a GSEControl element when fixedOffs attribute changed', async () => { - const input = inputs[4]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('fixedOffs'); - expect(updateAction.new.element).to.have.attribute('fixedOffs', 'true'); - }); - it('update a GSEControl element when securityEnabled attribute changed', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - input.value = 'SignatureAndEncryption'; - await input.requestUpdate(); - const editorAction = updateGseControlAction(gseControl); - const updateActions = editorAction(inputs, newWizard()); - expect(updateActions.length).to.equal(1); - expect(updateActions[0]).to.satisfy(isReplace); - const updateAction = updateActions[0]; - expect(updateAction.old.element).to.not.have.attribute('securityEnabled'); - expect(updateAction.new.element).to.have.attribute( - 'securityEnabled', - 'SignatureAndEncryption' - ); - }); - }); - - describe('define an create wizard that', () => { - let dataPicker: FinderList; - - describe('with existing ConnectedAP element in the Communication section', () => { - beforeEach(async () => { - const wizard = createGseControlWizard(doc.querySelector('LN0')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - (( - element.wizardUI.dialogs[0].querySelector( - 'wizard-textfield[label="appID"]' - ) - )).maybeValue = 'wer'; - - primaryAction = ( - element.wizardUI.dialogs[2]?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - dataPicker = ( - element.wizardUI.dialogs[2]?.querySelector('finder-list') - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('has three pages', () => - expect(element.wizardUI.dialogs.length).to.equal(3)); - - it('the first page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[0]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the second page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[1]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the third page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[2]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('triggers complex action on primary action click', async () => { - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('complex action carries GSEControl element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(6); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal( - 'GSEControl' - ); - }); - - it('add default confRev to the GSEControl element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(6); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).has.attribute('confRev', '1'); - }); - - it('complex action carries referenced DataSet element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(6); - const action = actions[5]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('DataSet'); - }); - - it('referenced DataSet element not having any FCDA per default', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(6); - - actions.forEach(action => { - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.not.equal( - 'FCDA' - ); - }); - }); - - it('referenced DataSet element saving selected FCDA', async () => { - const path = [ - 'Server: IED2>P1', - 'LDevice: IED2>>CircuitBreaker_CB1', - 'LN0: IED2>>CircuitBreaker_CB1', - 'DO: #Dummy.LLN0>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - dataPicker.paths = [path]; - await element.requestUpdate(); - - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(7); - const action = actions[6]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('FCDA'); - }); - - it('complex action adding GSE element in the Communication section', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(6); - const action = actions[1]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('GSE'); - }); - }); - - describe('with missing ConnectedAP element in the Communication section', () => { - beforeEach(async () => { - const wizard = createGseControlWizard( - doc.querySelector('IED[name="IED4"] LN0')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - (( - element.wizardUI.dialogs[0].querySelector( - 'wizard-textfield[label="appID"]' - ) - )).maybeValue = 'wer'; - - primaryAction = ( - element.wizardUI.dialogs[2]?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - dataPicker = ( - element.wizardUI.dialogs[2]?.querySelector('finder-list') - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('has three pages', () => - expect(element.wizardUI.dialogs.length).to.equal(3)); - - it('the second page having a warning message ', async () => { - await expect(element.wizardUI.dialogs[1]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('triggers complex action on primary action click', async () => { - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('referenced DataSet element not having any FCDA per default', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - - actions.forEach(action => { - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.not.equal( - 'FCDA' - ); - }); - }); - - it('referenced DataSet element saving selected FCDA', async () => { - const path = [ - 'Server: IED4>P1', - 'LDevice: IED4>>MU01', - 'LN0: IED4>>MU01', - 'DO: #Dummy.LLN0.two>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - dataPicker.paths = [path]; - await element.requestUpdate(); - - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(3); - const action = actions[2]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('FCDA'); - }); - - it('complex action NOT adding GSE element in the Communication section', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[1]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('DataSet'); - }); - }); - }); - - describe('define a wizard to select the control block reference', () => { - beforeEach(async () => { - const wizard = gseControlParentSelector(doc); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - }); -}); diff --git a/packages/plugins/test/unit/wizards/ied.test.ts b/packages/plugins/test/unit/wizards/ied.test.ts deleted file mode 100644 index 7ab54742dc..0000000000 --- a/packages/plugins/test/unit/wizards/ied.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { isSimple, ComplexAction } from '@openscd/core/foundation/deprecated/editor.js'; -import { - editIEDWizard, - removeIEDAndReferences, - removeIEDWizard, -} from '../../../src/wizards/ied.js'; - -import { - expectDeleteAction, - expectReplaceAction, - expectUpdateAction, - expectWizardNoUpdateAction, - fetchDoc, - setWizardTextFieldValue, -} from './test-support.js'; -import { updateNamingAttributeWithReferencesAction } from '../../../src/wizards/foundation/actions.js'; - -describe('Wizards for SCL element IED', () => { - let doc: XMLDocument; - let ied: Element; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - }); - - describe('edit IED', () => { - beforeEach(async () => { - ied = doc.querySelector('IED[name="IED3"]')!; - - element = await fixture( - html`` - ); - const wizard = editIEDWizard(ied); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - it('contains a wizard-textfield with a non-empty "type" value', async () => { - expect( - (inputs).find(textField => textField.label == 'type') - ?.value - ).to.be.equal(ied.getAttribute('type') || '-'); - }); - it('contains a wizard-textfield with a non-empty "manufacturer" value', async () => { - expect( - (inputs).find( - textField => textField.label == 'manufacturer' - )?.value - ).to.be.equal(ied.getAttribute('manufacturer') || '-'); - }); - it('contains a wizard-textfield with a non-empty "configVersion" value', async () => { - expect( - (inputs).find( - textField => textField.label == 'configVersion' - )?.value - ).to.be.equal(ied.getAttribute('configVersion') || '-'); - }); - it('contains a wizard-textfield with a non-empty "originalSclVersion" value', async () => { - expect( - (inputs).find( - textField => textField.label == 'originalSclVersion' - )?.value - ).to.contain(ied.getAttribute('originalSclVersion') || '-'); - }); - it('contains a wizard-textfield with an empty "engRight" value', async () => { - expect( - (inputs).find( - textField => textField.label == 'engRight' - )?.value - ).to.be.equal(ied.getAttribute('engRight') || '-'); - }); - it('contains a wizard-textfield with a non-empty "owner" value', async () => { - expect( - (inputs).find( - textField => textField.label == 'owner' - )?.value - ).to.be.equal(ied.getAttribute('owner') || '-'); - }); - it('update name should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], 'OtherIED3'); - - const complexAction = updateNamingAttributeWithReferencesAction( - ied, - 'ied.action.updateied' - )(inputs, element.wizardUI); - expect(complexAction.length).to.equal(1); - expect(complexAction[0]).to.not.satisfy(isSimple); - - const simpleActions = (complexAction[0]).actions; - expect(simpleActions.length).to.equal(2); - - expectUpdateAction(simpleActions[0], 'IED', 'name', 'IED3', 'OtherIED3'); - expectReplaceAction( - simpleActions[1], - 'ConnectedAP', - 'iedName', - 'IED3', - 'OtherIED3' - ); - }); - - it('update name should be unique in document', async function () { - await setWizardTextFieldValue(inputs[0], 'IED2'); - expect(inputs[0].checkValidity()).to.be.false; - }); - - it('update description should be updated in document', async function () { - await setWizardTextFieldValue( - inputs[1], - 'Some description' - ); - - const complexAction = updateNamingAttributeWithReferencesAction( - ied, - 'ied.action.updateied' - )(inputs, element.wizardUI); - expect(complexAction.length).to.equal(1); - expect(complexAction[0]).to.not.satisfy(isSimple); - - const simpleActions = (complexAction[0]).actions; - expect(simpleActions.length).to.equal(1); - - expectUpdateAction( - simpleActions[0], - 'IED', - 'desc', - null, - 'Some description' - ); - }); - - it('when no fields changed there will be no update action', async function () { - expectWizardNoUpdateAction( - updateNamingAttributeWithReferencesAction(ied, 'ied.action.updateied'), - element.wizardUI, - inputs - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('remove IED', () => { - beforeEach(async () => { - ied = doc.querySelector('IED[name="IED1"]')!; - - element = await fixture( - html`` - ); - const wizard = removeIEDWizard(ied); - element.workflow.push(() => wizard!); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('remove IED should return expected actions', async function () { - const complexAction = removeIEDAndReferences(ied)( - inputs, - element.wizardUI - ); - - expect(complexAction.length).to.equal(1); - expect(complexAction[0]).to.not.satisfy(isSimple); - - const simpleActions = (complexAction[0]).actions; - expect(simpleActions.length).to.equal(12); - - expectDeleteAction(simpleActions[0], 'IED'); - expectDeleteAction(simpleActions[1], 'Association'); - expectDeleteAction(simpleActions[2], 'ClientLN'); - expectDeleteAction(simpleActions[11], 'Inputs'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/ldevice.test.ts b/packages/plugins/test/unit/wizards/ldevice.test.ts deleted file mode 100644 index 8946bd49fe..0000000000 --- a/packages/plugins/test/unit/wizards/ldevice.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, - getValue, -} from '@openscd/open-scd/src/foundation.js'; -import { createUpdateAction } from '@openscd/core/foundation/deprecated/editor.js'; -import { editLDeviceWizard } from '../../../src/wizards/ldevice.js'; -import { - fetchDoc, - setWizardTextFieldValue, - expectUpdateAction, -} from './test-support.js'; - -describe('Wizards for SCL element LDevice', () => { - let doc: XMLDocument; - let ied: Element; - let services: Element; - let ldevice: Element; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - ied = doc.querySelector('IED[name="IED3"]')!; - services = ied.querySelector('Services')!; - ldevice = ied.querySelectorAll('AccessPoint > Server > LDevice')[0]; - element = await fixture( - html`` - ); - const wizard = editLDeviceWizard(ldevice); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('contains a wizard-textfield with a non-empty "inst" value', async () => { - expect( - (inputs).find(textField => textField.label == 'ldInst') - ?.value - ).to.be.equal(ldevice.getAttribute('inst')); - }); - it('contains a wizard-textfield with an empty "desc" value', async () => { - expect( - (inputs).find(textField => textField.label == 'desc') - ?.value - ).to.be.equal(''); - }); - it('contains a wizard-textfield with an empty "ldName" value', async () => { - expect( - (inputs).find(textField => textField.label == 'ldName') - ?.value - ).to.be.equal(''); - }); - - describe('Allowing/Disallowing ldName editing', () => { - it('ConfLdName should not be present and therefore ldName should be readonly', async function () { - expect(services.querySelector('ConfLdName')).to.not.exist; - expect(inputs[0]).to.have.attribute('readonly'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - it('ConfLdName should be present in IED1 and therefore ldName should not be readonly', async function () { - ied = doc.querySelector('IED[name="IED1"]')!; - services = ied.querySelector('Services')!; - ldevice = ied.querySelectorAll('AccessPoint > Server > LDevice')[0]; - element = await fixture( - html`` - ); - const wizard = editLDeviceWizard(ldevice); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - - expect(services.querySelector('ConfLdName')).to.exist; - expect(inputs[0]).to.not.have.attribute('readonly'); - - describe('Modify ldName', () => { - it('should be registered as an update action', async () => { - const newValue = 'LDevice1'; - const ldeviceTextField = (inputs).find( - textField => textField.label == 'ldName' - )!; - - expect(ldeviceTextField?.value).to.be.equal(''); - await setWizardTextFieldValue(ldeviceTextField, newValue); - - const ldNameVal = getValue(inputs.find(i => i.label === 'ldName')!)!; - expect(ldNameVal).to.not.be.equal(ldevice.getAttribute('ldName')); - - const simpleAction = createUpdateAction(ldevice, { - ldName: ldNameVal, - }); - - expectUpdateAction( - simpleAction, - ldevice.tagName, - ldeviceTextField.label, - null, - newValue - ); - }); - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/line.test.ts b/packages/plugins/test/unit/wizards/line.test.ts deleted file mode 100644 index 1016531b46..0000000000 --- a/packages/plugins/test/unit/wizards/line.test.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { SinonSpy, spy } from 'sinon'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { createLineWizard, editLineWizard } from '../../../src/wizards/line.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; - -describe('Wizards for SCL Line element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/editors/substation/Line.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editLineWizard(doc.querySelector('Line[name="Berlin"]')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - it('triggers simple edit action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - it('allows to create non required attribute desc', async () => { - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - it('allows to create non required attribute type', async () => { - inputs[2].value = 'someNonEmptyType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'type', - 'someNonEmptyType' - ); - }); - it('allows to create non required attribute nomFreq', async () => { - inputs[3].value = '50'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('nomFreq', '50'); - }); - it('allows to create non required attribute numPhases', async () => { - inputs[4].value = '3'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('numPhases', '3'); - }); - }); - - describe('define a create wizard that', () => { - beforeEach(async () => { - const wizard = createLineWizard( - doc.querySelector('Line[name="Berlin"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create required attributes name', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to create name and non required attribute desc', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - - it('allows to create name and non required attribute type', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'someNonEmptyType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'type', - 'someNonEmptyType' - ); - }); - - it('allows to create name and non required attribute nomFreq', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[3].value = '50'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute('nomFreq', '50'); - }); - - it('allows to create name and non required attribute numPhases', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[4].value = '3'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute('numPhases', '3'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/ln.test.ts b/packages/plugins/test/unit/wizards/ln.test.ts deleted file mode 100644 index 784c7bec10..0000000000 --- a/packages/plugins/test/unit/wizards/ln.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards'; - -import { editLNWizard } from '../../../src/wizards/ln.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { fetchDoc, setWizardTextFieldValue } from './test-support.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; - - - -describe('ln wizards', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - const values = { - lnType: 'LN-type', - desc: 'LN-description', - prefix: 'LN-prefix', - lnClass: 'LN-class', - inst: '1', - }; - const readonlyFields = [ - 'lnType', - 'prefix', - 'lnClass', - 'inst' - ]; - - const ln = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - - element = await fixture( - html`` - ); - const wizard = editLNWizard(ln); - - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - Object.entries(values).forEach(([key, value]) => { - it(`contains a wizard-textfield with a non-empty "${key}" value`, async () => { - expect( - (inputs).find( - (textField) => textField.label === key - )?.value - ).to.equal(value); - }); - }); - - readonlyFields.forEach((field) => { - it(`is a readonly field ${field}`, async () => { - const input = (inputs).find( - (textField) => textField.label === field - ) as WizardTextField; - - expect(input.readOnly).to.be.true; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/ln0.test.ts b/packages/plugins/test/unit/wizards/ln0.test.ts deleted file mode 100644 index b5e605059c..0000000000 --- a/packages/plugins/test/unit/wizards/ln0.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards'; - -import { editLN0Wizard } from '../../../src/wizards/ln0.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { fetchDoc, setWizardTextFieldValue } from './test-support.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; - - - -describe('ln0 wizards', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - const values = { - lnType: 'LN0-type', - desc: 'LN0-description', - lnClass: 'LN0-class', - inst: '1', - }; - const readonlyFields = [ - 'lnType', - 'lnClass', - 'inst' - ]; - - const ln = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/ied.scd'); - - element = await fixture( - html`` - ); - const wizard = editLN0Wizard(ln); - - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - Object.entries(values).forEach(([key, value]) => { - it(`contains a wizard-textfield with a non-empty "${key}" value`, async () => { - expect( - (inputs).find( - (textField) => textField.label === key - )?.value - ).to.equal(value); - }); - }); - - readonlyFields.forEach((field) => { - it(`is a readonly field ${field}`, async () => { - const input = (inputs).find( - (textField) => textField.label === field - ) as WizardTextField; - - expect(input.readOnly).to.be.true; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/lnode.test.ts b/packages/plugins/test/unit/wizards/lnode.test.ts deleted file mode 100644 index a9c3f44a8b..0000000000 --- a/packages/plugins/test/unit/wizards/lnode.test.ts +++ /dev/null @@ -1,399 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import fc from 'fast-check'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/test/mock-wizard-editor.js'; -import { MockWizardEditor } from '@openscd/open-scd/test/mock-wizard-editor.js'; - -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - newWizardEvent, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { regExp, regexString } from '../../foundation.js'; -import { editLNodeWizard, lNodeWizard } from '../../../src/wizards/lnode.js'; - -describe('Wizards for LNode element', () => { - let element: MockWizardEditor; - let doc: Document; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - let logEvent: SinonSpy; - - beforeEach(async () => { - doc = await fetch('/test/testfiles/lnodewizard.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - element = ( - await fixture(html``) - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - logEvent = spy(); - window.addEventListener('log', logEvent); - }); - - describe('contain a LNode instantiate wizard that', () => { - describe('with existing LLN0 and LPHD instances', () => { - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('Function[name="parentFunction"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - - describe('has a primary action that', () => { - let primaryAction: HTMLElement; - let listItems: ListItemBase[]; - - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('SubFunction[name="disconnector"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - listItems = Array.from( - element.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - }); - - it('triggers error log massage when duplicate LLN0 classes are added', async () => { - listItems[0].selected = true; - - primaryAction.click(); - - expect(logEvent).to.have.be.calledOnce; - expect(logEvent.args[0][0].detail.message).to.contain( - 'lnode.log.uniqueln0' - ); - }); - - it('triggers error log massage when duplicate LPHD classes are added', async () => { - listItems[1].selected = true; - - primaryAction.click(); - - expect(logEvent).to.have.be.calledOnce; - expect(logEvent.args[0][0].detail.message).to.contain( - 'lnode.log.uniqueln0' - ); - }); - - it('trigger error log message when not unique lnInst can be find', async () => { - const parent = doc.querySelector('SubFunction[name="disconnector"]')! - .parentElement!; - for (let i = 1; i <= 99; i++) { - const element = ( - doc.createElementNS(doc.documentElement.namespaceURI, 'LNode') - ); - - element.setAttribute('lnClass', 'CILO'); - element.setAttribute('lnInst', `${i}`); - parent.appendChild(element); - } - - listItems[4].selected = true; - - primaryAction.click(); - - expect(logEvent).to.have.be.calledOnce; - expect(logEvent.args[0][0].detail.message).to.contain( - 'lnode.log.nonuniquelninst' - ); - }); - }); - }); - - describe('with existing LLN0 but missing LPHD instances', () => { - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('SubFunction[name="circuitBreaker"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - }); - - describe('with missing LLN0 and LPHD instances', () => { - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('SubFunction[name="disconnector"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - }); - - describe('has a primary action that', () => { - let primaryAction: HTMLElement; - let listItems: ListItemBase[]; - - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('SubFunction[name="disconnector"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - listItems = Array.from( - element.wizardUI!.dialog!.querySelectorAll( - 'mwc-check-list-item' - ) - ); - }); - - it('triggers Create action for all selected LNodeType', async () => { - listItems[1].selected = true; - listItems[2].selected = true; - listItems[3].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledThrice; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - expect(actionEvent.args[1][0].detail.action).to.satisfy(isCreate); - expect(actionEvent.args[2][0].detail.action).to.satisfy(isCreate); - }); - - it('does set iedName, lnCalss, lnInst and lnType', async () => { - listItems[2].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action.new.element).to.have.attribute('iedName', 'None'); - expect(action.new.element).to.have.attribute('lnClass', 'XCBR'); - expect(action.new.element).to.have.attribute('lnInst', '1'); - expect(action.new.element).to.have.attribute('lnType', 'Dummy.XCBR1'); - }); - - it('does not set ldInst and prefix', async () => { - listItems[4].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action.new.element).to.not.have.attribute('ldInst'); - expect(action.new.element).to.not.have.attribute('prefix'); - }); - - it('makes sure that lnInst is unique in case lnClass is existing already', async () => { - listItems[4].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action.new.element).to.have.attribute('lnInst', '2'); - }); - - it('makes sure that lnInst is unique if several LNodeType with same lnClass are selected', async () => { - listItems[3].selected = true; - listItems[5].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledTwice; - const action1 = actionEvent.args[0][0].detail.action; - const action2 = actionEvent.args[1][0].detail.action; - expect(action1.new.element).to.have.attribute('lnInst', '2'); - expect(action2.new.element).to.have.attribute('lnInst', '4'); - }); - - it('does add empty string to LNode with lnClass LLN0', async () => { - listItems[0].selected = true; - - await primaryAction.click(); - - expect(actionEvent).to.have.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action.new.element).to.have.attribute('lnInst', ''); - }); - }); - }); - - describe('contain a LNode reference create wizard that', () => { - describe('with references to existing logical nodes', () => { - beforeEach(async () => { - const wizard = lNodeWizard( - doc.querySelector('ConductingEquipment[name="QB1"]')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - }); - - describe('with missing references to existing logical nodes', () => { - beforeEach(async () => { - const wizard = lNodeWizard(doc.querySelector('Substation')!); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - }); - }); - - describe('contain a edit wizard that', () => { - let inputs: WizardInputElement[]; - - describe('for a type reference', () => { - beforeEach(async () => { - const wizard = editLNodeWizard( - doc.querySelector('SubFunction[name="disconnector"] > LNode')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.updateComplete; - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - - it('edits prefix attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tAsciName, 1, 11), async name => { - inputs[2].value = name; - await (inputs[2]).requestUpdate(); - expect(inputs[2].checkValidity()).to.be.true; - }) - ); - }); - - it('rejects name attribute starting with decimals', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => { - inputs[2].value = name; - await (inputs[2]).requestUpdate(); - expect(inputs[2].checkValidity()).to.be.false; - }) - ); - }); - - it('rejects negative integrers for lnInst attribute', async () => { - inputs[4].value = '-1'; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.false; - }); - - it('rejects 0 for lnInst attribute', async () => { - inputs[4].value = '0'; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.false; - }); - - it('rejects positve integrers bigger 100 for lnInst attribute', async () => { - inputs[4].value = '100'; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.false; - }); - - it('rejects non unique lnInst attribute', async () => { - inputs[4].value = '3'; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.false; - }); - - it('does not update the LNode element when no attribute has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update a LNode element on prefix attribute changed', async () => { - const input = inputs[2]; - - input.nullSwitch?.click(); - input.value = 'somepref'; - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - - expect(action.old.element).to.not.have.attribute('prefix'); - expect(action.new.element).to.have.attribute('prefix', 'somepref'); - }); - - it('update a ReportControl element when only desc attribute changed', async () => { - const input = inputs[4]; - input.value = '34'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - - expect(action.old.element).to.have.attribute('lnInst', '1'); - expect(action.new.element).to.have.attribute('lnInst', '34'); - }); - }); - - describe('for a IED reference', () => { - beforeEach(async () => { - const wizard = editLNodeWizard( - doc.querySelector('Bay[name="COUPLING_BAY"] > LNode')! - ); - element.dispatchEvent(newWizardEvent(wizard)); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).to.equalSnapshot()); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/optfields.test.ts b/packages/plugins/test/unit/wizards/optfields.test.ts deleted file mode 100644 index de1d2d5bb7..0000000000 --- a/packages/plugins/test/unit/wizards/optfields.test.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { Replace, isReplace } from '@openscd/core/foundation/deprecated/editor.js'; -import { editOptFieldsWizard } from '../../../src/wizards/optfields.js'; - -describe('Wizards for SCL OptFields element', () => { - let element: OscdWizards; - let optFields: Element; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - optFields = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editOptFieldsWizard(optFields); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('does not update a OptFields element with no changed attributes', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update the OptFields element with changed dataSet attribute', async () => { - const input = inputs[2]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('dataSet', 'true'); - expect(updateAction.new.element).to.have.attribute('dataSet', 'false'); - }); - - it('removes the OptFields attribute dataSet with nulled select', async () => { - const input = inputs[2]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('dataSet', 'true'); - expect(updateAction.new.element).to.not.have.attribute('dataSet'); - }); - - it('updates the OptFields element with changed seqNum attribute', async () => { - const input = inputs[0]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('seqNum'); - expect(updateAction.new.element).to.have.attribute('seqNum', 'true'); - }); - - it('updates the OptFields element with changed timeStamp attribute', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('timeStamp'); - expect(updateAction.new.element).to.have.attribute('timeStamp', 'true'); - }); - - it('updates the OptFields element with changed reasonCode attribute', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('reasonCode'); - expect(updateAction.new.element).to.have.attribute('reasonCode', 'true'); - }); - - it('updates the OptFields element with changed dataRef attribute', async () => { - const input = inputs[4]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('dataRef'); - expect(updateAction.new.element).to.have.attribute('dataRef', 'true'); - }); - - it('updates the OptFields element with changed entryID attribute', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('entryID'); - expect(updateAction.new.element).to.have.attribute('entryID', 'true'); - }); - - it('updates the OptFields element with changed configRef attribute', async () => { - const input = inputs[6]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('configRef'); - expect(updateAction.new.element).to.have.attribute('configRef', 'true'); - }); - - it('updates the OptFields element with changed bufOvfl attribute', async () => { - const input = inputs[7]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('bufOvfl', 'true'); - expect(updateAction.new.element).to.have.attribute('bufOvfl', 'false'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/powertransformer.test.ts b/packages/plugins/test/unit/wizards/powertransformer.test.ts deleted file mode 100644 index b702798394..0000000000 --- a/packages/plugins/test/unit/wizards/powertransformer.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { replaceNamingAction } from '../../../src/wizards/foundation/actions.js'; - -import { - createAction, - createPowerTransformerWizard, - editPowerTransformerWizard, -} from '../../../src/wizards/powertransformer.js'; - -import { - executeWizardCreateAction, - executeWizardReplaceAction, - expectWizardNoUpdateAction, - fetchDoc, - setWizardTextFieldValue, -} from './test-support.js'; - -describe('Wizards for SCL element Power Transformer', () => { - let doc: XMLDocument; - let powerTransformer: Element; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - describe('edit existing Power Transformer', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/valid2007B4withSubstationXY.scd'); - powerTransformer = doc.querySelector('PowerTransformer[name="TA1"]')!; - - element = await fixture( - html`` - ); - const wizard = editPowerTransformerWizard(powerTransformer); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update name should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], 'OtherTA1'); - - const updateAction = executeWizardReplaceAction( - replaceNamingAction(powerTransformer), - element.wizardUI, - inputs - ); - expect(updateAction.old.element).to.have.attribute('name', 'TA1'); - expect(updateAction.new.element).to.have.attribute('name', 'OtherTA1'); - }); - - it('update description should be updated in document', async function () { - await setWizardTextFieldValue( - inputs[1], - 'Some description' - ); - - const updateAction = executeWizardReplaceAction( - replaceNamingAction(powerTransformer), - element.wizardUI, - inputs - ); - expect(updateAction.old.element).to.not.have.attribute('desc'); - expect(updateAction.new.element).to.have.attribute( - 'desc', - 'Some description' - ); - }); - - it('when no fields changed there will be no update action', async function () { - expectWizardNoUpdateAction( - replaceNamingAction(powerTransformer), - element.wizardUI, - inputs - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('add new Power Transformer', () => { - let parent: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/valid2007B4withSubstationXY.scd'); - parent = doc.querySelector('Substation[name="AA1"]')!; - - element = await fixture( - html`` - ); - const wizard = createPowerTransformerWizard(parent); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('create new Power Transformer', async function () { - await setWizardTextFieldValue(inputs[0], 'NewTA1'); - - const createAC = executeWizardCreateAction( - createAction(parent), - element.wizardUI, - inputs - ); - expect(createAC.new.element).to.have.attribute('name', 'NewTA1'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/process.test.ts b/packages/plugins/test/unit/wizards/process.test.ts deleted file mode 100644 index 0bac36af83..0000000000 --- a/packages/plugins/test/unit/wizards/process.test.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { SinonSpy, spy } from 'sinon'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isReplace, - Create, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createProcessWizard, - editProcessWizard, -} from '../../../src/wizards/process.js'; - -describe('Wizards for SCL Process element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/editors/substation/Process.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editProcessWizard( - doc.querySelector('Process[name="ProcessGenConduct"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('triggers simple edit action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to create non required attribute desc', async () => { - (inputs[1]).nullSwitch?.click(); - inputs[1].value = 'someDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - expect(editAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - it('allows to create non required attribute type', async () => { - (inputs[2]).nullSwitch?.click(); - inputs[2].value = 'someNonEmptyType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'type', - 'someNonEmptyType' - ); - }); - }); - describe('define a create wizard that', () => { - beforeEach(async () => { - const wizard = createProcessWizard( - doc.querySelector('Process[name="ProcessGenConduct"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create required attributes name', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to create name and non required attribute desc', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - - it('allows to create name and non required attribute type', async () => { - inputs[0].value = 'someNonEmptyName'; - inputs[2].value = 'someNonEmptyType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'type', - 'someNonEmptyType' - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/reportcontrol.test.ts b/packages/plugins/test/unit/wizards/reportcontrol.test.ts deleted file mode 100644 index 9f9d0383a4..0000000000 --- a/packages/plugins/test/unit/wizards/reportcontrol.test.ts +++ /dev/null @@ -1,742 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; -import fc, { integer } from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isSimple, - ComplexAction, - Create, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - reportControlParentSelector, - createReportControlWizard, - editReportControlWizard, - removeReportControlAction, - selectReportControlWizard, - reportControlCopyToIedSelector, -} from '../../../src/wizards/reportcontrol.js'; -import { inverseRegExp, regExp, regexString } from '../../foundation.js'; -import { FinderList } from '@openscd/open-scd/src/finder-list.js'; -import { FilteredList } from '@openscd/open-scd/src/filtered-list.js'; -import { ListItemBase } from '@material/mwc-list/mwc-list-item-base'; - -describe('Wizards for SCL ReportControl element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/wizards/reportcontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - describe('for complete ReportControl element', () => { - beforeEach(async () => { - const wizard = editReportControlWizard( - doc.querySelector('ReportControl')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('edits name attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => { - inputs[0].value = name; - await (inputs[0]).requestUpdate(); - expect(inputs[0].checkValidity()).to.be.true; - }) - ); - }); - - it('rejects name attribute starting with decimals', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => { - inputs[0].value = name; - await (inputs[0]).requestUpdate(); - expect(inputs[0].checkValidity()).to.be.false; - }) - ); - }); - - it('edits bufTime attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty( - integer({ min: 0 }).map(num => `${num}`), - async bufTime => { - inputs[6].value = bufTime; - await (inputs[6]).requestUpdate(); - expect(inputs[6].checkValidity()).to.be.true; - } - ) - ); - }); - - it('rejects bufTime attribute starting with not being a unsigned int', async () => { - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.uint, 1), - async bufTime => { - inputs[6].value = bufTime; - await (inputs[6]).requestUpdate(); - expect(inputs[6].checkValidity()).to.be.false; - } - ) - ); - }); - - it('edits intgPd attribute only for valid inputs', async () => { - const input = inputs[7]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - await fc.assert( - fc.asyncProperty( - integer({ min: 0 }).map(num => `${num}`), - async intgPd => { - input.value = intgPd; - await input.requestUpdate(); - expect(input.checkValidity()).to.be.true; - } - ) - ); - }); - - it('rejects intgPd attribute starting with not being a unsigned int', async () => { - const input = inputs[7]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - await fc.assert( - fc.asyncProperty(regexString(inverseRegExp.uint, 1), async intgPd => { - input.value = intgPd; - await input.requestUpdate(); - expect(input.checkValidity()).to.be.false; - }) - ); - }); - - it('does not update the ReportControl element when no attribute nor Val has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update a ReportControl element when only name attribute changed', async () => { - const input = inputs[0]; - input.value = 'myNewCbName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.have.attribute('name', 'ReportCb'); - expect(updateAction.new.element).to.have.attribute( - 'name', - 'myNewCbName' - ); - }); - - it('update a ReportControl element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.not.have.attribute('desc'); - expect(updateAction.new.element).to.have.attribute('desc', 'myDesc'); - }); - - it('update a ReportControl element when rptID attribute changed', async () => { - const input = inputs[3]; - input.value = 'myNewType/ID'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.have.attribute( - 'rptID', - 'reportCb1' - ); - expect(updateAction.new.element).to.have.attribute( - 'rptID', - 'myNewType/ID' - ); - }); - - it('update a ReportControl element when indexed attribute changed', async () => { - const input = inputs[4]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.have.attribute('indexed', 'true'); - expect(updateAction.new.element).to.have.attribute('indexed', 'false'); - }); - - it('update a ReportControl element when bufTime attribute changed', async () => { - const input = inputs[6]; - input.value = '54'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.have.attribute('bufTime', '100'); - expect(updateAction.new.element).to.have.attribute('bufTime', '54'); - }); - - it('update a ReportControl element when intgPd attribute changed', async () => { - const input = inputs[7]; - input.nullSwitch?.click(); - input.value = '1000'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.old.element).to.not.have.attribute('intgPd'); - expect(updateAction.new.element).to.have.attribute('intgPd', '1000'); - }); - - it('updates the RptEnable element with changed max attribute', async () => { - const input = inputs[5]; - input.value = '6'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - - const updateAction = (action).actions[0]; - expect(updateAction.new.element.tagName).to.equal('RptEnabled'); - expect(updateAction.old.element.tagName).to.equal('RptEnabled'); - expect(updateAction.old.element).to.have.attribute('max', '5'); - expect(updateAction.new.element).to.have.attribute('max', '6'); - }); - - describe('with missing RptEnabled child', () => { - beforeEach(async () => { - const wizard = editReportControlWizard( - doc.querySelector('ReportControl[name="ReportCb2"]')! - ); - element.workflow.length = 0; - await element.requestUpdate(); - - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('nulles max Client input', () => { - const input = inputs[5]; - expect(input.maybeValue).to.be.null; - }); - - it('creates a RptEnable element when max Client activated', async () => { - doc.querySelector('ReportControl>RptEnabled')!.remove(); - - const input = inputs[5]; - input.nullSwitch?.click(); - input.value = '6'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - expect((action).actions[0]).to.satisfy(isCreate); - - const updateAction = (action).actions[0]; - expect((updateAction.new.element).tagName).to.equal( - 'RptEnabled' - ); - expect(updateAction.new.element).to.have.attribute('max', '6'); - }); - }); - - describe('contains a remove button that', () => { - const ln01gse = new DOMParser().parseFromString( - ` - - - - - `, - 'application/xml' - ).documentElement; - - const ln02gse = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02rp = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02smv = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const missingparent = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - it('removes ReportControl and its referenced DataSet if no other ReportControl are assigned', () => { - const reportControl = ln01gse.querySelector('ReportControl')!; - const actions = ( - removeReportControlAction(reportControl)!.actions - ); - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(reportControl); - expect(actions[1]).to.satisfy(isDelete); - expect(actions[1].old.element).to.equal( - ln01gse.querySelector('DataSet') - ); - }); - - it('does not remove if another ReportControl is assigned to the same DataSet', () => { - const reportControl = ln02gse.querySelector('ReportControl')!; - const actions = ( - removeReportControlAction(reportControl)!.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(reportControl); - }); - - it('does not remove if another GSEControl is assigned to the same DataSet', () => { - const reportControl = ln02rp.querySelector('ReportControl')!; - const actions = ( - removeReportControlAction(reportControl)!.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(reportControl); - }); - - it('does not remove if another SMV is assigned to the same DataSet', () => { - const reportControl = ln02smv.querySelector('ReportControl')!; - const actions = ( - removeReportControlAction(reportControl)!.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(reportControl); - }); - - it('does not remove with missing parent element', () => { - const action = removeReportControlAction(missingparent); - expect(action).to.be.null; - }); - }); - }); - - describe('for ReportControl with missing child elements and referenced DataSet', () => { - beforeEach(async () => { - const ln0 = new DOMParser().parseFromString( - '', - 'application/xml' - ); - - const reportControl = ln0.querySelector('ReportControl')!; - - const wizard = editReportControlWizard(reportControl); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - }); - }); - - describe('define a select wizard that', () => { - describe('with existing ReportControl element', () => { - beforeEach(async () => { - const wizard = selectReportControlWizard(doc.documentElement); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()).timeout( - 5000 - ); - }); - - describe('with invalid parent', () => { - beforeEach(async () => { - const wizard = selectReportControlWizard(doc.querySelector('DO')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()).timeout( - 5000 - ); - }); - }); - - describe('define an create wizard that', () => { - let dataPicker: FinderList; - - beforeEach(async () => { - const wizard = createReportControlWizard(doc.querySelector('LN0')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialogs[3]?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - dataPicker = ( - element.wizardUI.dialogs[3]?.querySelector('finder-list') - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('has four pages', () => - expect(element.wizardUI.dialogs.length).to.equal(4)); - - it('the first page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[0]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the second page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[1]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the third page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[2]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the forth page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[3]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('triggers complex action on primary action click', async () => { - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('complex action carries ReportControl element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal( - 'ReportControl' - ); - }); - - it('add default confRev to the ReportControlElement', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).has.attribute('confRev', '1'); - }); - - it('complex action carries referenced DataSet element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[1]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('DataSet'); - }); - - it('referenced DataSet element not having any FCDA per default', async () => { - await primaryAction.click(); - - const createAction = ( - (actionEvent.args[0][0].detail.action).actions[1] - ); - expect((createAction.new.element).children).to.be.empty; - }); - - it('referenced DataSet element saving selected FCDA', async () => { - const path = [ - 'Server: IED2>P1', - 'LDevice: IED2>>CircuitBreaker_CB1', - 'LN0: IED2>>CircuitBreaker_CB1', - 'DO: #Dummy.LLN0>Beh', - 'DA: #Dummy.LLN0.Beh>stVal', - ]; - - dataPicker.paths = [path]; - await element.requestUpdate(); - - await primaryAction.click(); - - const createAction = ( - (actionEvent.args[0][0].detail.action).actions[1] - ); - expect((createAction.new.element).children).to.not.be.empty; - expect((createAction.new.element).children).to.have.lengthOf(1); - }); - - it('complex action adding OptField element as child element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - const optFields = (createAction.new.element).querySelector( - 'OptFields' - ); - expect(optFields).to.exist; - expect(optFields).to.have.attribute('seqNum', 'true'); - }); - - it('complex action adding TrgOps element as child element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - const trgOps = (createAction.new.element).querySelector( - 'TrgOps' - ); - expect(trgOps).to.exist; - expect(trgOps).to.have.attribute('dchg', 'true'); - expect(trgOps).to.have.attribute('gi', 'false'); - }); - - it('complex action adding RptEnabled element as child element with non nulled max Client', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - const rptEnabled = (createAction.new.element).querySelector( - 'RptEnabled' - ); - expect(rptEnabled).to.exist; - expect(rptEnabled).to.have.attribute('max', '5'); - }); - - it('complex action adding RptEnabled element as child element with nulled max Client', async () => { - const max = ( - element.wizardUI.dialogs[0].querySelector( - 'wizard-textfield[label="max Clients"]' - ) - ); - max.nullSwitch?.click(); - await max.requestUpdate(); - - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - const rptEnabled = (createAction.new.element).querySelector( - 'RptEnabled' - ); - expect(rptEnabled).to.not.exist; - }); - }); - - describe('define a wizard to select the control block reference', () => { - beforeEach(async () => { - const wizard = reportControlParentSelector(doc); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - }); - - describe('define copy to other IED selector', () => { - let iedsPicker: FilteredList; - let listItem: ListItemBase; - - beforeEach(async () => { - const sourceReportControl = doc.querySelector( - 'IED[name="IED2"] ReportControl[name="ReportCb"]' - )!; - const wizard = reportControlCopyToIedSelector(sourceReportControl); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - iedsPicker = ( - element.wizardUI.dialog?.querySelector('filtered-list') - ); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('allows to copy to multiple IED at once', () => - expect(iedsPicker.multi).to.be.true); - - describe('with a sink IED not meeting partially the data references', () => { - beforeEach(async () => { - listItem = iedsPicker.items.find(item => item.value.includes('IED5'))!; - await element.requestUpdate(); - }); - - it('disabled the list item', () => - expect(listItem.disabled).to.not.be.true); - - it('does copy the control block ', () => { - listItem.click(); - primaryAction.click(); - expect(actionEvent).to.have.been.called; - }); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/sampledvaluecontrol.test.ts b/packages/plugins/test/unit/wizards/sampledvaluecontrol.test.ts deleted file mode 100644 index 833e3cd99b..0000000000 --- a/packages/plugins/test/unit/wizards/sampledvaluecontrol.test.ts +++ /dev/null @@ -1,676 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isReplace, - isSimple, - ComplexAction, - Create, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createSampledValueControlWizard, - editSampledValueControlWizard, - removeSampledValueControlAction, - selectSampledValueControlWizard, -} from '../../../src/wizards/sampledvaluecontrol.js'; -import fc, { integer } from 'fast-check'; -import { inverseRegExp, regExp, regexString } from '../../foundation.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; -import { FinderList } from '@openscd/open-scd/src/finder-list.js'; - -describe('Wizards for SCL element SampledValueControl', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/wizards/sampledvaluecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - describe('with muticast attribute set to false - deprecated', () => { - beforeEach(async () => { - const wizard = editSampledValueControlWizard( - doc.querySelector('SampledValueControl[multicast="false"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('update a SampledValueControl element when only multicast attribute changed', async () => { - ((inputs[2])).checked = true; - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute( - 'multicast', - 'false' - ); - expect(updateAction.new.element).to.have.attribute('multicast', 'true'); - }); - }); - - describe(' with multicast set to treu', () => { - beforeEach(async () => { - const wizard = editSampledValueControlWizard( - doc.querySelector('SampledValueControl[multicast="true"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('edits name attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.tAsciName, 1, 32), async name => { - inputs[0].value = name; - await (inputs[0]).requestUpdate(); - expect(inputs[0].checkValidity()).to.be.true; - }) - ); - }); - - it('rejects name attribute starting with decimals', async () => { - await fc.assert( - fc.asyncProperty(regexString(regExp.decimal, 1, 1), async name => { - inputs[0].value = name; - await (inputs[0]).requestUpdate(); - expect(inputs[0].checkValidity()).to.be.false; - }) - ); - }); - - it('edits smpRate attribute only for valid inputs', async () => { - await fc.assert( - fc.asyncProperty( - integer({ min: 0 }).map(num => `${num}`), - async smpRate => { - inputs[4].value = smpRate; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.true; - } - ) - ); - }); - - it('rejects smpRate attribute in case input is not unsigned int', async () => { - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.uint, 1), - async smpRate => { - inputs[4].value = smpRate; - await (inputs[4]).requestUpdate(); - expect(inputs[4].checkValidity()).to.be.false; - } - ) - ); - }); - - it('edits nofASDU attribute only for valid inputs', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - await fc.assert( - fc.asyncProperty( - integer({ min: 0 }).map(num => `${num}`), - async nofASDU => { - input.value = nofASDU; - await input.requestUpdate(); - expect(input.checkValidity()).to.be.true; - } - ) - ); - }); - - it('rejects nofASDU attribute in case input is not unsigned int', async () => { - const input = inputs[5]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - await fc.assert( - fc.asyncProperty( - regexString(inverseRegExp.uint, 1), - async nofASDU => { - input.value = nofASDU; - await input.requestUpdate(); - expect(input.checkValidity()).to.be.false; - } - ) - ); - }); - - it('does not update the SampledValueControl element when no attribute has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update a SampledValueControl element when only name attribute changed', async () => { - const input = inputs[0]; - input.value = 'myNewCbName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('name', 'MSVCB01'); - expect(updateAction.new.element).to.have.attribute( - 'name', - 'myNewCbName' - ); - }); - - it('update a SampledValueControl element when only desc attribute changed', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.value = 'myDesc'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('desc'); - expect(updateAction.new.element).to.have.attribute('desc', 'myDesc'); - }); - - it('update a SampledValueControl element when smvID attribute changed', async () => { - const input = inputs[2]; - input.value = 'myNewType/ID'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute( - 'smvID', - 'some/reference' - ); - expect(updateAction.new.element).to.have.attribute( - 'smvID', - 'myNewType/ID' - ); - }); - - it('update a SampledValueControl element when smpMod attribute changed', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.value = 'SmpPerSec'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('smpMod'); - expect(updateAction.new.element).to.have.attribute( - 'smpMod', - 'SmpPerSec' - ); - }); - - it('update a SampledValueControl element when smpRate attribute changed', async () => { - const input = inputs[4]; - input.value = '4000'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('smpRate', '80'); - expect(updateAction.new.element).to.have.attribute('smpRate', '4000'); - }); - - it('update a SampledValueControl element when nofASDU attribute changed', async () => { - const input = inputs[5]; - input.value = '2'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('nofASDU', '1'); - expect(updateAction.new.element).to.have.attribute('nofASDU', '2'); - }); - - it('updates the SampledValueEnable element when securityEnabled changed', async () => { - const input = inputs[6]; - input.nullSwitch?.click(); - input.value = 'Signature'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute( - 'securityEnabled' - ); - expect(updateAction.new.element).to.have.attribute( - 'securityEnabled', - 'Signature' - ); - }); - }); - - describe('contains a remove button that', () => { - const ln01smv = new DOMParser().parseFromString( - ` - - - - - `, - 'application/xml' - ).documentElement; - - const ln02smv2 = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02gse = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const ln02rp = new DOMParser().parseFromString( - ` - - - - `, - 'application/xml' - ).documentElement; - - const missingparent = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - it('removes SampledValueControl and its referenced DataSet if no other SampledValueControl is assigned', () => { - const sampledValueControl = ln01smv.querySelector( - 'SampledValueControl' - )!; - const actions = ( - removeSampledValueControlAction(sampledValueControl)?.actions - ); - expect(actions.length).to.equal(2); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(sampledValueControl); - expect(actions[1]).to.satisfy(isDelete); - expect(actions[1].old.element).to.equal( - ln01smv.querySelector('DataSet') - ); - }); - - it('does not remove DataSet with another SampledValueControl referenced', () => { - const sampledValueControl = ln02smv2.querySelector( - 'SampledValueControl' - )!; - const actions = ( - removeSampledValueControlAction(sampledValueControl)?.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(sampledValueControl); - }); - - it('does not remove DataSet with another GSEControl referenced', () => { - const sampledValueControl = ln02gse.querySelector( - 'SampledValueControl' - )!; - const actions = ( - removeSampledValueControlAction(sampledValueControl)?.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(sampledValueControl); - }); - - it('does not remove DataSet with another ReportControl referenced', () => { - const sampledValueControl = ln02rp.querySelector( - 'SampledValueControl' - )!; - const actions = ( - removeSampledValueControlAction(sampledValueControl)?.actions - ); - expect(actions.length).to.equal(1); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(sampledValueControl); - }); - - it('does not remove with missing parent element', () => { - const action = removeSampledValueControlAction(missingparent); - expect(action).to.be.null; - }); - - it('removes referenced SMV element in the Communication section', () => { - const sampledValueControl = doc.querySelector( - 'IED[name="IED3"] SampledValueControl' - )!; - const actions = ( - removeSampledValueControlAction(sampledValueControl)?.actions - ); - expect(actions.length).to.equal(3); - expect(actions[0]).to.satisfy(isDelete); - expect(actions[0].old.element).to.equal(sampledValueControl); - expect(actions[1]).to.satisfy(isDelete); - expect(actions[2]).to.satisfy(isDelete); - expect(actions[2].old.element).to.equal( - doc.querySelector( - 'Communication SMV[ldInst="MU01"][cbName="MSVCB01"]' - ) - ); - }); - }); - }); - - describe('define an create wizard that', () => { - let dataPicker: FinderList; - - describe('with existing ConnectedAP element in the Communication section', () => { - beforeEach(async () => { - const wizard = createSampledValueControlWizard( - doc.querySelector('IED[name="IED3"] LN0')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - (( - element.wizardUI.dialogs[0].querySelector( - 'wizard-textfield[label="smvID"]' - ) - )).maybeValue = 'wer'; - - primaryAction = ( - element.wizardUI.dialogs[3]?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - dataPicker = ( - element.wizardUI.dialogs[3]?.querySelector('finder-list') - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('has fourth pages', () => - expect(element.wizardUI.dialogs.length).to.equal(4)); - - it('the first page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[0]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the second page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[1]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the third page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[2]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('the fourth page looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialogs[3]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('triggers complex action on primary action click', async () => { - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('complex action carries SampledValueControl element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(3); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal( - 'SampledValueControl' - ); - }); - - it('add default confRev to the SampledValueControl element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(3); - const action = actions[0]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).has.attribute('confRev', '1'); - }); - - it('complex action carries referenced DataSet element', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(3); - const action = actions[2]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('DataSet'); - }); - - it('referenced DataSet element not having any FCDA per default', async () => { - await primaryAction.click(); - - const createAction = ( - (actionEvent.args[0][0].detail.action).actions[2] - ); - expect((createAction.new.element).children).to.be.empty; - }); - - it('referenced DataSet element saving selected FCDA', async () => { - const path = [ - 'Server: IED3>P1', - 'LDevice: IED3>>MU01', - 'LN0: IED3>>MU01', - 'DO: #DummyTCTR>Amp', - 'DA: #DummySAV>instMag', - 'BDA: #AnalogueValue_i>i', - ]; - - dataPicker.paths = [path]; - await element.requestUpdate(); - - await primaryAction.click(); - - const createAction = ( - (actionEvent.args[0][0].detail.action).actions[2] - ); - expect((createAction.new.element).children).to.not.be.empty; - expect((createAction.new.element).children).to.have.lengthOf( - 1 - ); - }); - - it('complex action adding SMV element in the Communication section', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(3); - const action = actions[1]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('SMV'); - }); - }); - - describe('with missing ConnectedAP element in the Communication section', () => { - beforeEach(async () => { - const wizard = createSampledValueControlWizard( - doc.querySelector('IED[name="IED4"] LN0')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - (( - element.wizardUI.dialogs[0].querySelector( - 'wizard-textfield[label="smvID"]' - ) - )).maybeValue = 'wer'; - - primaryAction = ( - element.wizardUI.dialogs[3]?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - dataPicker = ( - element.wizardUI.dialogs[3]?.querySelector('finder-list') - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('has fourth pages', () => - expect(element.wizardUI.dialogs.length).to.equal(4)); - - it('the third page having a warning message ', async () => { - await expect(element.wizardUI.dialogs[2]).dom.to.equalSnapshot(); - }).timeout(5000); - - it('triggers complex action on primary action click', async () => { - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.not.satisfy(isSimple); - }); - - it('complex action NOT adding SMV element in the Communication section', async () => { - await primaryAction.click(); - - const actions = (actionEvent.args[0][0].detail.action) - .actions; - expect(actions.length).to.equal(2); - const action = actions[1]; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect((createAction.new.element).tagName).to.equal('DataSet'); - }); - }); - }); - - describe('define a select wizard that', () => { - beforeEach(async () => { - const wizard = selectSampledValueControlWizard(doc.documentElement); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - }); -}); diff --git a/packages/plugins/test/unit/wizards/services.test.ts b/packages/plugins/test/unit/wizards/services.test.ts deleted file mode 100644 index 3036f7d19e..0000000000 --- a/packages/plugins/test/unit/wizards/services.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { isEmptyObject } from '../../../src/wizards/services.js'; - -describe('Wizards for SCL element Services', () => { - it('Simple empty input object is empty', () => { - const sut = { - foo: '', - }; - - expect(isEmptyObject(sut)).to.be.true; - }); - it('Complex empty input object is empty', () => { - const sut = { - foo: { - bar: '', - }, - }; - expect(isEmptyObject(sut)).to.be.true; - }); - it('Simple filled input object is not empty', () => { - const sut = { - foo: 'bar', - }; - expect(isEmptyObject(sut)).to.be.false; - }); - it('Complex filled input object is not empty', () => { - const sut = { - foo: { - bar: 'qux', - }, - }; - expect(isEmptyObject(sut)).to.be.false; - }); -}); diff --git a/packages/plugins/test/unit/wizards/smv.test.ts b/packages/plugins/test/unit/wizards/smv.test.ts deleted file mode 100644 index 5b7142da03..0000000000 --- a/packages/plugins/test/unit/wizards/smv.test.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; -import fc, { hexaString, integer } from 'fast-check'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - Create, - Delete, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { editSMvWizard } from '../../../src/wizards/smv.js'; -import { invertedRegex, MAC, regExp } from '../../foundation.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; - -describe('Wizards for SCL element SMV', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/wizards/sampledvaluecontrol.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editSMvWizard(doc.querySelector('SMV')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - inputs = Array.from(element.wizardUI.inputs); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - - describe('contains an input to edit P element of type MAC-Address', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'MAC-Address'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty(MAC(), async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - }) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(invertedRegex(regExp.MAC), async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - }); - - describe('contains an input to edit P element of type APPID', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'APPID'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - hexaString({ minLength: 4, maxLength: 4 }), - async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(hexaString({ minLength: 5 }), async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - - it('does not allow to edit characters < 4', async () => - await fc.assert( - fc.asyncProperty( - hexaString({ minLength: 0, maxLength: 3 }), - async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - } - ) - )); - }); - - describe('contains an input to edit P element of type VLAN-ID', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'VLAN-ID'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - hexaString({ minLength: 3, maxLength: 3 }), - async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty(hexaString({ minLength: 4 }), async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - }) - )); - - it('does not allow to edit characters < 3', async () => - await fc.assert( - fc.asyncProperty( - hexaString({ minLength: 0, maxLength: 2 }), - async testValue => { - input!.value = testValue.toUpperCase(); - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - } - ) - )); - }); - - describe('contains an input to edit P element of type VLAN-PRIORITY', () => { - beforeEach(() => { - input = inputs.find(input => input.label === 'VLAN-PRIORITY'); - }); - - it('is always rendered', () => expect(input).to.exist); - - it('allow to edit for valid input', async () => - await fc.assert( - fc.asyncProperty( - integer({ min: 0, max: 7 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.true; - } - ) - )); - - it('does not allow to edit for invalid input', async () => - await fc.assert( - fc.asyncProperty( - integer({ min: 8 }).map(num => `${num}`), - async testValue => { - input!.value = testValue; - await element.requestUpdate(); - expect(input!.checkValidity()).to.be.false; - } - ) - )); - }); - - it('does not update SMV element when no P element has changed', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('properly updates a P element of type MAC-Address', async () => { - input = ( - inputs.find(input => input.label === 'MAC-Address') - ); - input.value = '01-0C-CD-01-01-00'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - expect( - oldAddress.querySelector('P[type="MAC-Address"]')?.textContent - ).to.equal('01-0C-CD-04-00-20'); - expect( - newAddress.querySelector('P[type="MAC-Address"]')?.textContent - ).to.equal('01-0C-CD-01-01-00'); - }); - - it('properly updates a P element of type APPID', async () => { - input = inputs.find(input => input.label === 'APPID'); - input.value = '001A'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - expect( - oldAddress.querySelector('P[type="APPID"]')?.textContent - ).to.equal('4002'); - expect( - newAddress.querySelector('P[type="APPID"]')?.textContent - ).to.equal('001A'); - }); - - it('properly updates a P element of type VLAN-ID', async () => { - input = inputs.find(input => input.label === 'VLAN-ID'); - input.value = '07D'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - expect( - oldAddress.querySelector('P[type="VLAN-ID"]')?.textContent - ).to.equal('007'); - expect( - newAddress.querySelector('P[type="VLAN-ID"]')?.textContent - ).to.equal('07D'); - }); - - it('properly updates a P element of type VLAN-PRIORITY', async () => { - input = ( - inputs.find(input => input.label === 'VLAN-PRIORITY') - ); - input.value = '3'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - const complexAction = actionEvent.args[0][0].detail.action; - - const oldAddress = ( - (complexAction.actions[0]).old.element - ); - const newAddress = ( - (complexAction.actions[1]).new.element - ); - - expect( - oldAddress.querySelector('P[type="VLAN-PRIORITY"]') - ?.textContent - ).to.equal('4'); - expect( - newAddress.querySelector('P[type="VLAN-PRIORITY"]') - ?.textContent - ).to.equal('3'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/smvopts.test.ts b/packages/plugins/test/unit/wizards/smvopts.test.ts deleted file mode 100644 index ec2ff12e0c..0000000000 --- a/packages/plugins/test/unit/wizards/smvopts.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; -import { Replace, isReplace } from '@openscd/core/foundation/deprecated/editor.js'; -import { editSmvOptsWizard } from '../../../src/wizards/smvopts.js'; - -describe('Wizards for SCL SmvOpts element', () => { - let element: OscdWizards; - let smvOpts: Element; - let inputs: WizardCheckbox[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - smvOpts = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editSmvOptsWizard(smvOpts); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = (Array.from(element.wizardUI.inputs)); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('does not update a SmvOpts element with no changed attributes', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('update the SmvOpts element with changed dataSet attribute', async () => { - const input = inputs[2]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('dataSet', 'true'); - expect(updateAction.new.element).to.have.attribute('dataSet', 'false'); - }); - - it('removes the SmvOpts attribute dataSet with nulled select', async () => { - const input = inputs[2]; - input.nullSwitch?.click(); - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('dataSet', 'true'); - expect(updateAction.new.element).to.not.have.attribute('dataSet'); - }); - - it('updates the SmvOpts element with changed refreshTime attribute', async () => { - const input = inputs[0]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('refreshTime', 'true'); - expect(updateAction.new.element).to.have.attribute( - 'refreshTime', - 'false' - ); - }); - - it('updates the SmvOpts element with changed sampleRate attribute', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('sampleRate'); - expect(updateAction.new.element).to.have.attribute('sampleRate', 'true'); - }); - - it('updates the SmvOpts element with changed security attribute', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('security'); - expect(updateAction.new.element).to.have.attribute('security', 'true'); - }); - - it('updates the SmvOpts element with changed synchSourceId attribute', async () => { - const input = inputs[4]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('synchSourceId'); - expect(updateAction.new.element).to.have.attribute( - 'synchSourceId', - 'true' - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/sub-equipment.test.ts b/packages/plugins/test/unit/wizards/sub-equipment.test.ts deleted file mode 100644 index 2a296db314..0000000000 --- a/packages/plugins/test/unit/wizards/sub-equipment.test.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - Create, - Replace, - isCreate, - isReplace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - editSubEquipmentWizard, - createSubEquipmentWizard, -} from '../../../src/wizards/subequipment.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; - -describe('Wizards for SCL SubEquipment element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/SubEquipment.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createSubEquipmentWizard( - doc.querySelector('SubEquipment')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple create action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.not.have.attribute('desc'); - }); - - it('allows to create non required attribute virtual', async () => { - inputs[0].value = 'someNonEmptyName'; - - const virtualCheckbox: WizardCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch?.click(); - virtualCheckbox.checked = true; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('virtual', 'true'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editSubEquipmentWizard(doc.querySelector('SubEquipment')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action without changes', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action if name attribute is not unique', async () => { - inputs[0].value = 'addEqi'; - primaryAction.click(); - await element.updateComplete; - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple replace action updating name attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('triggers simple replace action updating desc attribute', async () => { - inputs[1].value = 'someDesc'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - - it('triggers simple replace action updating phase attribute', async () => { - inputs[2].value = 'AB'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('phase', 'AB'); - }); - - it('triggers simple replace action updating virtual attribute', async () => { - const virtualCheckbox: WizardCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch?.click(); - virtualCheckbox.checked = true; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('virtual', 'true'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/subfunction.test.ts b/packages/plugins/test/unit/wizards/subfunction.test.ts deleted file mode 100644 index 6d14cb3924..0000000000 --- a/packages/plugins/test/unit/wizards/subfunction.test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - Create, - Replace, - isCreate, - isReplace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createSubFunctionWizard, - editSubFunctionWizard, -} from '../../../src/wizards/subfunction.js'; - -describe('Wizards for SCL Function element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('test/testfiles/zeroline/functions.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an create wizard that', () => { - beforeEach(async () => { - const wizard = createSubFunctionWizard(doc.querySelector('Function')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple create action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.not.have.attribute('desc'); - expect(createAction.new.element).to.not.have.attribute('type'); - }); - - it('allows to create non required attributes desc and type', async () => { - inputs[0].value = 'someNonEmptyName'; - - (inputs[1]).nullSwitch?.click(); - (inputs[2]).nullSwitch?.click(); - inputs[1].value = 'SomeDesc'; - inputs[2].value = 'SomeType'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('desc', 'SomeDesc'); - expect(createAction.new.element).to.have.attribute('type', 'SomeType'); - }); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editSubFunctionWizard( - doc.querySelector( - 'Bay[name="COUPLING_BAY"] > Function[name="bayName"] > SubFunction[name="myBaySubFunc"]' - )! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action without changes', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('does not trigger action if name attribute is not unique', async () => { - inputs[0].value = 'mySubFunc2'; - primaryAction.click(); - await element.updateComplete; - - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple replace action updating name attribute', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('triggers simple replace action updating desc attribute', async () => { - inputs[1].value = 'someDesc'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('desc', 'someDesc'); - }); - - it('triggers simple replace action updating type attribute', async () => { - inputs[2].value = 'someType'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const createAction = action; - - expect(createAction.new.element).to.have.attribute('type', 'someType'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/subnetwork.test.ts b/packages/plugins/test/unit/wizards/subnetwork.test.ts deleted file mode 100644 index dfe18d7157..0000000000 --- a/packages/plugins/test/unit/wizards/subnetwork.test.ts +++ /dev/null @@ -1,451 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, - patterns, -} from '@openscd/open-scd/src/foundation.js'; -import { - isCreate, - isDelete, - isReplace, - Create, - Delete, - Replace -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createSubNetworkWizard, - editSubNetworkWizard, -} from '../../../src/wizards/subnetwork.js'; - -describe('Wizards for SCL element SubNetwork', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - let input: WizardInputElement | undefined; - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('include an edit wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - }); - - describe('with existing BitRate child element', () => { - beforeEach(async () => { - const wizard = editSubNetworkWizard(doc.querySelector('SubNetwork')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - //work around, because the escapes get removed in snapshot - it('should have correct pattern', async () => { - expect( - element.wizardUI.dialog!.querySelectorAll( - 'wizard-textfield[pattern]' - )!.length - ).to.equal(2); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.decimal); - }); - - it('does not edit any attributes with unchanged wizard inputs', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers an editor action to update name attribute', async () => { - input = inputs.find(input => input.label === 'name'); - input.value = 'newSubNetName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isReplace); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.old.element).to.have.a.attribute( - 'name', - 'StationBus' - ); - expect(updateAction.new.element).to.have.a.attribute( - 'name', - 'newSubNetName' - ); - }); - - it('triggers an editor action to update desc attribute', async () => { - input = inputs.find(input => input.label === 'desc'); - await input.requestUpdate(); - - (input).nullSwitch?.click(); - input.value = 'myNewSubNetworkDesc'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isReplace); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.old.element).to.not.have.a.attribute('desc'); - expect(updateAction.new.element).to.have.a.attribute( - 'desc', - 'myNewSubNetworkDesc' - ); - }); - - it('triggers an editor action to update type attribute', async () => { - input = inputs.find(input => input.label === 'type'); - input.value = 'myNewSubNetType'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isReplace); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.old.element).to.have.a.attribute('type', '8-MMS'); - expect(updateAction.new.element).to.have.a.attribute( - 'type', - 'myNewSubNetType' - ); - }); - - it('triggers an editor action to update BitRate element', async () => { - input = ( - inputs.find(input => input.label === 'BitRate') - ); - input.value = '200.'; - (input).multiplier = 'M'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isReplace); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.old.element.innerHTML.trim()).to.equal('100.0'); - expect(updateAction.old.element).to.not.have.attribute('multiplier'); - expect(updateAction.new.element.innerHTML.trim()).to.equal('200.'); - expect(updateAction.new.element).to.have.attribute('multiplier', 'M'); - }); - - it('triggers an editor action to remove BitRate element', async () => { - input = ( - inputs.find(input => input.label === 'BitRate') - ); - await input.requestUpdate(); - - (input).nullSwitch?.click(); - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isDelete); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.old.element.textContent?.trim()).to.equal('100.0'); - expect(updateAction.old.element).to.not.have.attribute('multiplier'); - }); - }); - - describe('with missing BitRate child element', () => { - beforeEach(async () => { - const wizard = editSubNetworkWizard( - doc.querySelector('SubNetwork[name="ProcessBus"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - //work around, because the escapes get removed in snapshot - it('should have correct pattern', async () => { - expect( - element.wizardUI.dialog!.querySelectorAll( - 'wizard-textfield[pattern]' - )!.length - ).to.equal(2); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.decimal); - }); - - it('triggers an editor action to create a complete BitRate element', async () => { - input = ( - inputs.find(input => input.label === 'BitRate') - ); - await input.requestUpdate(); - - (input).nullSwitch?.click(); - (input).value = '100.0'; - (input).multiplier = 'M'; - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.new.element.textContent?.trim()).to.equal('100.0'); - expect(updateAction.new.element).to.have.attribute('multiplier', 'M'); - }); - - it('triggers an editor action to create BitRate element with multiplier only', async () => { - input = ( - inputs.find(input => input.label === 'BitRate') - ); - await input.requestUpdate(); - - (input).nullSwitch?.click(); - (input).multiplier = 'M'; - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.new.element.textContent?.trim()).to.equal(''); - expect(updateAction.new.element).to.have.attribute('multiplier'); - }); - - it('triggers an editor action to create BitRate element with bit rate only', async () => { - input = ( - inputs.find(input => input.label === 'BitRate') - ); - await input.requestUpdate(); - - (input).nullSwitch?.click(); - (input).value = '100.0'; - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.new.element.textContent?.trim()).to.equal('100.0'); - expect(updateAction.new.element).to.not.have.attribute('multiplier'); - }); - }); - }); - - describe('include an create wizard that', () => { - beforeEach(async () => { - doc = await fetch('/test/testfiles/valid2003.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = createSubNetworkWizard( - doc.querySelector('Communication')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot({ - ignoreAttributes: [ - { - tags: ['wizard-textfield'], - attributes: ['pattern'], - }, - ], - }); - }); - - //work around, because the escapes get removed in snapshot - it('should have correct pattern', async () => { - expect( - element.wizardUI.dialog!.querySelectorAll('wizard-textfield[pattern]')! - .length - ).to.equal(2); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[0] - .getAttribute('pattern') - ).to.equal(patterns.normalizedString); - - expect( - element.wizardUI - .dialog!.querySelectorAll('wizard-textfield[pattern]')[1] - .getAttribute('pattern') - ).to.equal(patterns.decimal); - }); - - it('does not allow creating SubNetwork with empty name attribute', async () => { - input = inputs.find(input => input.label === 'name'); - input.value = ''; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.not.be.called; - }); - - it('triggers an editor action to create SubNetwork element including BitRate', async () => { - input = inputs.find(input => input.label === 'name'); - input.value = 'myNewSubNetworkName'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.new.element).to.have.a.attribute( - 'name', - 'myNewSubNetworkName' - ); - expect(updateAction.new.element).to.have.a.attribute('desc', ''); - expect(updateAction.new.element).to.have.a.attribute('type', '8-MMS'); - expect((updateAction.new.element).querySelector('BitRate')).to - .exist; - expect( - (updateAction.new.element).querySelector('BitRate') - ).to.have.attribute('multiplier', 'M'); - expect( - (updateAction.new.element) - .querySelector('BitRate') - ?.textContent?.trim() - ).to.equal('100'); - }); - - it('triggers an editor action to create SubNetwork element excluding non required /BitRate', async () => { - const name = ( - inputs.find(input => input.label === 'name') - ); - const desc = ( - inputs.find(input => input.label === 'desc') - ); - const type = ( - inputs.find(input => input.label === 'type') - ); - const bitrate = ( - inputs.find(input => input.label === 'BitRate') - ); - await element.requestUpdate(); - - desc.nullSwitch?.click(); - type.nullSwitch?.click(); - bitrate.nullSwitch?.click(); - name.value = 'myNewSubNetworkName'; - await name.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - - expect(actionEvent).to.be.calledOnce; - expect(actionEvent.args[0][0].detail.action).to.satisfy(isCreate); - - const updateAction = actionEvent.args[0][0].detail.action; - expect(updateAction.new.element).to.have.a.attribute( - 'name', - 'myNewSubNetworkName' - ); - expect(updateAction.new.element).to.not.have.a.attribute('desc'); - expect(updateAction.new.element).to.not.have.a.attribute('type'); - expect((updateAction.new.element).querySelector('BitRate')).to - .not.exist; - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/substation.test.ts b/packages/plugins/test/unit/wizards/substation.test.ts deleted file mode 100644 index 77fdbc90ef..0000000000 --- a/packages/plugins/test/unit/wizards/substation.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { isSimple, ComplexAction } from '@openscd/core/foundation/deprecated/editor.js'; - -import { - executeWizardCreateAction, - expectReplaceAction, - expectUpdateAction, - expectWizardNoUpdateAction, - fetchDoc, - setWizardTextFieldValue, -} from './test-support.js'; -import { updateNamingAttributeWithReferencesAction } from '../../../src/wizards/foundation/actions.js'; -import { - createAction, - createSubstationWizard, - substationEditWizard, -} from '../../../src/wizards/substation.js'; - -describe('Wizards for SCL element Substation', () => { - let doc: XMLDocument; - let substation: Element; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - describe('edit existing Substation', () => { - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/substation.scd'); - substation = doc.querySelector('Substation[name="Sub1"]')!; - - element = await fixture( - html`` - ); - const wizard = substationEditWizard(substation); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('update name should be updated in document', async function () { - await setWizardTextFieldValue(inputs[0], 'OtherSub1'); - - const complexAction = updateNamingAttributeWithReferencesAction( - substation, - 'substation.action.updatesubstation' - )(inputs, element.wizardUI); - expect(complexAction.length).to.equal(1); - expect(complexAction[0]).to.not.satisfy(isSimple); - - const simpleActions = (complexAction[0]).actions; - expect(simpleActions.length).to.equal(7); - - expectUpdateAction( - simpleActions[0], - 'Substation', - 'name', - 'Sub1', - 'OtherSub1' - ); - expectReplaceAction( - simpleActions[1], - 'Terminal', - 'substationName', - 'Sub1', - 'OtherSub1' - ); - }); - - it('update description should be updated in document', async function () { - await setWizardTextFieldValue( - inputs[1], - 'Some description' - ); - - const complexAction = updateNamingAttributeWithReferencesAction( - substation, - 'substation.action.updatesubstation' - )(inputs, element.wizardUI); - expect(complexAction.length).to.equal(1); - expect(complexAction[0]).to.not.satisfy(isSimple); - - const simpleActions = (complexAction[0]).actions; - expect(simpleActions.length).to.equal(1); - - expectUpdateAction( - simpleActions[0], - 'Substation', - 'desc', - 'Substation 1', - 'Some description' - ); - }); - - it('when no fields changed there will be no update action', async function () { - expectWizardNoUpdateAction( - updateNamingAttributeWithReferencesAction( - substation, - 'substation.action.updatesubstation' - ), - element.wizardUI, - inputs - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); - - describe('add new Substation', () => { - let parent: Element; - - beforeEach(async () => { - doc = await fetchDoc('/test/testfiles/wizards/substation.scd'); - parent = doc.querySelector('SCL')!; - - element = await fixture( - html`` - ); - const wizard = createSubstationWizard(parent); - element.workflow.push(() => wizard); - await element.requestUpdate(); - inputs = Array.from(element.wizardUI.inputs); - }); - - it('create new Substation', async function () { - await setWizardTextFieldValue(inputs[0], 'NewSub'); - - const createAC = executeWizardCreateAction( - createAction(parent), - element.wizardUI, - inputs - ); - expect(createAC.new.element).to.have.attribute('name', 'NewSub'); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/tapchanger.test.ts b/packages/plugins/test/unit/wizards/tapchanger.test.ts deleted file mode 100644 index 1ea8938ed4..0000000000 --- a/packages/plugins/test/unit/wizards/tapchanger.test.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardInputElement } from '@openscd/open-scd/src/foundation.js'; -import { - Create, - Replace, - isCreate, - isReplace, -} from '@openscd/core/foundation/deprecated/editor.js'; -import { - createTapChangerWizard, - editTapChangerWizard, -} from '../../../src/wizards/tapchanger.js'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; - -describe('Wizards for SCL TapChanger element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/editors/substation/TapChanger.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editTapChangerWizard( - doc.querySelector('TapChanger[name="tapChComplet"]')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple edit action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to unset non required attribute virtual', async () => { - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'false'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('virtual', 'false'); - }); - - it('allows to create non required attribute desc', async () => { - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - }); - - describe('define a create wizard that', () => { - beforeEach(async () => { - const wizard = createTapChangerWizard( - doc.querySelector('TransformerWinding')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create required attributes name', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - - expect(createAction.new.element).to.not.have.attribute('desc'); - }); - - it('allows to create name and non required attribute virtual', async () => { - inputs[0].value = 'someNonEmptyName'; - - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('virtual', 'true'); - }); - - it('allows to create name and non required attribute desc', async () => { - inputs[0].value = 'someNonEmptyName'; - const descField = ( - element.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await element.updateComplete; - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/terminal.test.ts b/packages/plugins/test/unit/wizards/terminal.test.ts deleted file mode 100644 index 824b89fbe1..0000000000 --- a/packages/plugins/test/unit/wizards/terminal.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { editTerminalWizard } from '../../../src/wizards/terminal.js'; - -describe('Wizards for SCL element Terminal', () => { - let doc: XMLDocument; - let element: OscdWizards; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch('/test/testfiles/valid2007B4withSubstationXY.scd') - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - const wizard = editTerminalWizard(doc.querySelector('Terminal')!); - element.workflow.push(() => wizard); - await element.requestUpdate(); - }); - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }); -}); diff --git a/packages/plugins/test/unit/wizards/test-support.ts b/packages/plugins/test/unit/wizards/test-support.ts deleted file mode 100644 index 85a6ba1440..0000000000 --- a/packages/plugins/test/unit/wizards/test-support.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { expect } from '@open-wc/testing'; - -import { - WizardActor, - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { - SimpleAction, - Create, - Delete, - Replace, - Update, - isCreate, - isDelete, - isReplace, - isUpdate -} from '@openscd/core/foundation/deprecated/editor.js'; -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; - -export async function setWizardTextFieldValue( - field: WizardTextField, - value: string | null -): Promise { - if (field.nullSwitch && !field.nullSwitch.checked) { - field.nullSwitch?.click(); - } - field.maybeValue = value; - await field.requestUpdate(); -} - -export async function setWizardSelectValue( - field: WizardSelect, - value: string | null -): Promise { - if (field.nullSwitch && !field.nullSwitch.checked) { - field.nullSwitch?.click(); - } - field.maybeValue = value; - await field.requestUpdate(); -} - -export function executeWizardReplaceAction( - wizardActor: WizardActor, - wizard: Element, - inputs: WizardInputElement[] -): Replace { - const replaceActions = wizardActor(inputs, wizard); - expect(replaceActions.length).to.equal(1); - expect(replaceActions[0]).to.satisfy(isReplace); - return replaceActions[0]; -} - -export function executeWizardCreateAction( - wizardActor: WizardActor, - wizard: Element, - inputs: WizardInputElement[] -): Create { - const createActions = wizardActor(inputs, wizard); - expect(createActions.length).to.equal(1); - expect(createActions[0]).to.satisfy(isCreate); - return createActions[0]; -} - -export function expectWizardNoUpdateAction( - wizardActor: WizardActor, - wizard: Element, - inputs: WizardInputElement[] -): void { - const updateActions = wizardActor(inputs, wizard); - expect(updateActions).to.be.empty; -} - -export function expectReplaceAction( - simpleAction: SimpleAction, - tagName: string, - attributeName: string, - oldValue: string | null, - newValue: string | null -): void { - expect(simpleAction).to.satisfy(isReplace); - - expect((simpleAction).old.element.tagName).to.be.equal(tagName); - if (oldValue === null) { - expect((simpleAction).old.element).to.not.have.attribute( - attributeName - ); - } else { - expect((simpleAction).old.element).to.have.attribute( - attributeName, - oldValue - ); - } - - expect((simpleAction).new.element.tagName).to.be.equal(tagName); - if (newValue === null) { - expect((simpleAction).new.element).to.not.have.attribute( - attributeName - ); - } else { - expect((simpleAction).new.element).to.have.attribute( - attributeName, - newValue - ); - } -} - -export function expectUpdateAction( - simpleAction: SimpleAction, - tagName: string, - attributeName: string, - oldValue: string | null, - newValue: string | null -): void { - expect(simpleAction).to.satisfy(isUpdate); - - expect((simpleAction).element.tagName).to.be.equal(tagName); - const oldAttributes = (simpleAction).oldAttributes; - if (oldValue === null) { - expect(Object.keys(oldAttributes)).to.not.contain(attributeName); - } else { - expect(Object.keys(oldAttributes)).to.contain(attributeName); - expect(Object.values(oldAttributes)).to.contain(oldValue); - } - - const newAttributes = (simpleAction).newAttributes; - if (newValue === null) { - expect(Object.keys(newAttributes)).to.not.contain(attributeName); - } else { - expect(Object.keys(newAttributes)).to.contain(attributeName); - expect(Object.values(newAttributes)).to.contain(newValue); - } -} - -export function expectUpdateTextValue( - action: Replace, - parentTagName: string, - oldValue: string, - newValue: string -): void { - expect(action.old.element.parentElement!.tagName).to.be.equal(parentTagName); - expect(action.old.element.textContent).to.be.equal(oldValue); - expect(action.new.element.textContent).to.be.equal(newValue); -} - -export async function fetchDoc(docName: string): Promise { - return await fetch(docName) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); -} - -export function expectDeleteAction( - simpleAction: SimpleAction, - tagName: string -): void { - expect(simpleAction).to.satisfy(isDelete); - - const oldElement = (simpleAction).old.element; - expect((oldElement).tagName).to.be.equal(tagName); -} diff --git a/packages/plugins/test/unit/wizards/transformerwinding.test.ts b/packages/plugins/test/unit/wizards/transformerwinding.test.ts deleted file mode 100644 index b29d48e004..0000000000 --- a/packages/plugins/test/unit/wizards/transformerwinding.test.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { WizardTextField } from '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { Create, Replace, isCreate, isReplace } from '@openscd/core/foundation/deprecated/editor.js'; -import { - createTransformerWindingWizard, - editTransformerWindingWizard, -} from '../../../src/wizards/transformerWinding'; -import { WizardCheckbox } from '@openscd/open-scd/src/wizard-checkbox.js'; - -describe('Wizards for SCL TransformerWinding element', () => { - let doc: XMLDocument; - let element: OscdWizards; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - doc = await fetch( - '/test/testfiles/editors/substation/TransformerWinding.scd' - ) - .then(response => response.text()) - .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editTransformerWindingWizard( - doc.querySelector('TransformerWinding')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - inputs[0].value = ''; - await element.requestUpdate(); - await primaryAction.click(); - expect(actionEvent).to.not.have.been.called; - }); - - it('triggers simple edit action on primary action click', async () => { - inputs[0].value = 'someNonEmptyName'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - }); - - it('allows to create non required attribute virtual', async () => { - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute('virtual', 'true'); - }); - - it('allows to create non required attribute desc', async () => { - const descField = ( - element.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await element.updateComplete; - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - const editAction = action; - - expect(editAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - }); - - describe('define a create wizard that', () => { - beforeEach(async () => { - const wizard = createTransformerWindingWizard( - doc.querySelector('PowerTransformer')! - ); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - - await element.wizardUI.requestUpdate(); // make sure wizard is rendered - }); - - it('looks like the the latest snapshot', async () => - await expect(element.wizardUI.dialog).dom.to.equalSnapshot()); - - it('does not accept empty name attribute', async () => { - await primaryAction.click(); - - expect(actionEvent).to.not.have.been.called; - }); - - it('allows to create required attributes name', async () => { - inputs[0].value = 'someNonEmptyName'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - - expect(createAction.new.element).to.not.have.attribute('desc'); - }); - - it('allows to create name and non required attribute virtual', async () => { - inputs[0].value = 'someNonEmptyName'; - - const virtualCheckbox = ( - element.wizardUI.dialog?.querySelector( - 'wizard-checkbox[label="virtual"]' - ) - ); - - virtualCheckbox.nullSwitch!.click(); - virtualCheckbox.maybeValue = 'true'; - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - expect(createAction.new.element).to.have.attribute( - 'name', - 'someNonEmptyName' - ); - expect(createAction.new.element).to.have.attribute('virtual', 'true'); - }); - - it('allows to create name and non required attribute desc', async () => { - inputs[0].value = 'someNonEmptyName'; - const descField = ( - element.wizardUI.dialog?.querySelector('wizard-textfield[label="desc"]') - ); - - await new Promise(resolve => setTimeout(resolve, 100)); // await animation - descField.nullSwitch!.click(); - await element.updateComplete; - inputs[1].value = 'someNonEmptyDesc'; - - await element.requestUpdate(); - await primaryAction.click(); - - expect(actionEvent).to.be.calledOnce; - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isCreate); - const createAction = action; - - expect(createAction.new.element).to.have.attribute( - 'desc', - 'someNonEmptyDesc' - ); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/trgops.test.ts b/packages/plugins/test/unit/wizards/trgops.test.ts deleted file mode 100644 index 3c67951b06..0000000000 --- a/packages/plugins/test/unit/wizards/trgops.test.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { SinonSpy, spy } from 'sinon'; - -import '@openscd/open-scd/src/addons/Wizards.js'; -import { OscdWizards } from '@openscd/open-scd/src/addons/Wizards.js'; - -import { - WizardInputElement, -} from '@openscd/open-scd/src/foundation.js'; -import { Replace, isReplace} from '@openscd/core/foundation/deprecated/editor.js'; -import { WizardSelect } from '@openscd/open-scd/src/wizard-select.js'; -import { editTrgOpsWizard } from '../../../src/wizards/trgops.js'; - -describe('Wizards for SCL TrgOps element', () => { - let element: OscdWizards; - let trgOps: Element; - let inputs: WizardInputElement[]; - - let primaryAction: HTMLElement; - - let actionEvent: SinonSpy; - - beforeEach(async () => { - element = await fixture( - html`` - ); - trgOps = ( - new DOMParser().parseFromString( - ``, - 'application/xml' - ).documentElement - ); - - actionEvent = spy(); - window.addEventListener('editor-action', actionEvent); - }); - - describe('define an edit wizard that', () => { - beforeEach(async () => { - const wizard = editTrgOpsWizard(trgOps); - element.workflow.push(() => wizard); - await element.requestUpdate(); - - inputs = Array.from(element.wizardUI.inputs); - await element.requestUpdate(); - - primaryAction = ( - element.wizardUI.dialog?.querySelector( - 'mwc-button[slot="primaryAction"]' - ) - ); - }); - - it('looks like the latest snapshot', async () => { - await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); - }).timeout(5000); - - it('does not update the TrgOps element with no changed attributes', async () => { - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent.notCalled).to.be.true; - }); - - it('updates the TrgOps element with changed dchg attribute', async () => { - const input = inputs[0]; - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('dchg', 'true'); - expect(updateAction.new.element).to.have.attribute('dchg', 'false'); - }); - - it('updates the TrgOps element with changed qchg attribute', async () => { - const input = inputs[1]; - input.nullSwitch?.click(); - input.maybeValue = 'false'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('qchg'); - expect(updateAction.new.element).to.have.attribute('qchg', 'false'); - }); - - it('updates the TrgOps element with changed dupd attribute', async () => { - const input = inputs[2]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('dupd'); - expect(updateAction.new.element).to.have.attribute('dupd', 'true'); - }); - - it('updates the TrgOps element with changed gi attribute', async () => { - const input = inputs[4]; - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.have.attribute('gi', 'false'); - expect(updateAction.new.element).to.have.attribute('gi', 'true'); - }); - - it('updates the TrgOps element with changed period attribute', async () => { - const input = inputs[3]; - input.nullSwitch?.click(); - input.maybeValue = 'true'; - await input.requestUpdate(); - - primaryAction.click(); - await element.requestUpdate(); - expect(actionEvent).to.be.calledOnce; - - const action = actionEvent.args[0][0].detail.action; - expect(action).to.satisfy(isReplace); - - const updateAction = action; - expect(updateAction.old.element).to.not.have.attribute('period'); - expect(updateAction.new.element).to.have.attribute('period', 'true'); - }); - }); -}); diff --git a/packages/plugins/test/unit/wizards/voltagelevel.test.ts b/packages/plugins/test/unit/wizards/voltagelevel.test.ts deleted file mode 100644 index 2707f7a0cf..0000000000 --- a/packages/plugins/test/unit/wizards/voltagelevel.test.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { fixture, html, expect } from '@open-wc/testing'; - -import '@openscd/open-scd/src/wizard-textfield.js'; -import { - WizardInputElement, - WizardActor, -} from '@openscd/open-scd/src/foundation.js'; -import { - ComplexAction, - isCreate, - isReplace, - isDelete, - isSimple, - } from '@openscd/core/foundation/deprecated/editor.js'; -import { - createAction, - updateAction, -} from '../../../src/wizards/voltagelevel.js'; - -describe('VoltageLevelEditor', () => { - const noOp = () => { - return; - }; - const newWizard = (done = noOp) => { - const element = document.createElement('mwc-dialog'); - element.close = done; - return element; - }; - - let inputs: WizardInputElement[]; - beforeEach(async () => { - inputs = await Promise.all( - ['name', 'desc', 'nomFreq', 'numPhases', 'Voltage'].map( - label => - >( - fixture( - html`` - ) - ) - ) - ); - }); - - function getAndValidComplexAction(wizardActor: WizardActor): ComplexAction { - const editorActions = wizardActor(inputs, newWizard()); - expect(editorActions.length).to.equal(1); - expect(editorActions[0]).to.not.satisfy(isSimple); - return editorActions[0]; - } - - describe('with no nulled properties', () => { - describe('has a createAction that', () => { - let parent: Element; - beforeEach(() => { - parent = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns a Create EditorAction', () => { - const wizardAction = createAction(parent); - expect(wizardAction(inputs, newWizard())[0]).to.satisfy(isCreate); - }); - }); - - describe('has an updateAction that', () => { - describe('with missing child element Voltage', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns two EditorActions', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions.length).to.equal(2); - }); - - it('returns a WizardAction with the first returned EditorAction being an Update', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[0]).to.satisfy(isReplace); - }); - - it('returns a WizardAction with the second returned EditorAction being a Create', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[1]).to.satisfy(isCreate); - }); - }); - - describe('with present child element Voltage', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - ` - 110 - `, - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns two EditorActions', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions.length).to.equal(2); - }); - - it('returns a WizardAction with the first returned EditorAction being an Update', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[0]).to.satisfy(isReplace); - }); - - it('returns a WizardAction with the second returned EditorAction being a Update', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[1]).to.satisfy(isReplace); - }); - }); - - describe('with no change in element VoltageLevel but changes in the child element Voltage', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - ` - 110 - `, - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction which returns one EditorActions', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions.length).to.equal(1); - }); - - it('returns a WizardAction with the first returned EditorAction beeing an Update', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[0]).to.satisfy(isReplace); - }); - }); - - describe('with no change in VoltageLevel nor Voltage', () => { - let element: Element; - beforeEach(() => { - element = new DOMParser().parseFromString( - '', - 'application/xml' - ).documentElement; - }); - - it('returns a WizardAction with an empty EditorActions array', () => { - const wizardAction = updateAction(element); - expect(wizardAction(inputs, newWizard()).length).to.equal(0); - }); - }); - }); - }); - - describe('with nulled properties', () => { - - describe('has an updateAction that', () => { - describe('with present child element Voltage', () => { - let element: Element; - beforeEach(async () => { - element = new DOMParser().parseFromString( - ` - 110 - `, - 'application/xml' - ).documentElement; - - inputs[4] = await fixture(html``); - }); - - it('returns a WizardAction which returns two EditorActions', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions.length).to.equal(2); - }); - - it('returns a WizardAction with the first returned EditorAction beeing an Update', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[0]).to.satisfy(isReplace); - }); - - it('returns a WizardAction with the second returned EditorAction beeing a Delete', () => { - const wizardAction = updateAction(element); - const complexAction = getAndValidComplexAction(wizardAction); - expect(complexAction.actions[1]).to.satisfy(isDelete); - }); - }); - }); - }); -}); diff --git a/packages/plugins/tsconfig.json b/packages/plugins/tsconfig.json deleted file mode 100644 index 73197f94a7..0000000000 --- a/packages/plugins/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "module": "esnext", - "moduleResolution": "node", - "noEmitOnError": true, - "lib": ["es2020", "dom"], - "strict": true, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "importHelpers": true, - "allowJs": true, - "skipLibCheck": true, - "outDir": "dist", - "sourceMap": true, - "inlineSources": true, - "resolveJsonModule": true, - "rootDir": "./src" - }, - "include": ["src/**/*.ts"] -} diff --git a/packages/plugins/web-test-runner.config.mjs b/packages/plugins/web-test-runner.config.mjs deleted file mode 100644 index 4386b9bd4c..0000000000 --- a/packages/plugins/web-test-runner.config.mjs +++ /dev/null @@ -1,61 +0,0 @@ -// import { playwrightLauncher } from '@web/test-runner-playwright'; -import { esbuildPlugin } from '@web/dev-server-esbuild'; -import { playwrightLauncher } from '@web/test-runner-playwright'; - - -export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({ - /** we run test directly on TypeScript files */ - plugins: [esbuildPlugin({ ts: true })], - - /** Resolve bare module imports */ - nodeResolve: true, - - /** filter browser logs - * Plugins have a fix URL and do not fit to the file structure in test environment. - * Creating open-scd in the tests leads to error in the browser log - we had to disable the browser log - */ - browserLogs: false, - - /** specify groups for unit and integrations tests - * hint: no --group definition runs all groups - */ - groups: [ - { - name: 'unit', - files: 'test/unit/**/*.test.ts', - }, - { - name: 'integration', - files: 'test/integration/**/*.test.ts', - }, - // { - // name: 'single', - // files: 'test/integration/validators/ValidateTemplates.test.ts', - // }, - ], - - /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */ - // esbuildTarget: 'auto', - - /** Amount of browsers to run concurrently */ - // concurrentBrowsers: 2, - - /** Amount of test files per browser to test concurrently */ - // concurrency: 1, - - /** Browsers to run tests on */ - browsers: [ - playwrightLauncher({ - // concurrency: 1, - product: 'chromium', - launchOptions: { - headless: true, - devtools: false, - }, - }), - // playwrightLauncher({ product: 'firefox' }), - // playwrightLauncher({ product: 'webkit' }), - ], - - // See documentation for all available options -}); diff --git a/packages/plugins/workbox-config.cjs b/packages/plugins/workbox-config.cjs deleted file mode 100644 index e50b12aabb..0000000000 --- a/packages/plugins/workbox-config.cjs +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - globDirectory: 'build/', - globPatterns: [ - 'public/**/*.{md,js,png,xml,pdf,css,html,info,json,ico,svg,wasm}', - 'src/**/*.{md,js,png,xml,pdf,css,html,info,json,ico,svg,wasm}', - '*.{md,js,png,xml,pdf,css,html,info,json,ico,svg,wasm}', - ], - swDest: 'build/sw.js', - runtimeCaching: [ - { - urlPattern: /.*/, - handler: 'NetworkFirst', - }, - ], - skipWaiting: true, - inlineWorkboxRuntime: true, -};