diff --git a/bundles/org.openhab.ui/web/package-lock.json b/bundles/org.openhab.ui/web/package-lock.json index 980b496b3e..ecfdfba73a 100644 --- a/bundles/org.openhab.ui/web/package-lock.json +++ b/bundles/org.openhab.ui/web/package-lock.json @@ -9,13 +9,15 @@ "version": "3.0.0", "license": "EPL-2.0", "dependencies": { - "@blockly/field-slider": "^2.1.10", - "@blockly/zoom-to-fit": "^2.0.24", + "@blockly/field-slider": "^4.0.3", + "@blockly/plugin-cross-tab-copy-paste": "^2.0.4", + "@blockly/theme-dark": "^4.0.1", + "@blockly/zoom-to-fit": "^3.0.3", "@jsep-plugin/arrow": "^1.0.5", "@jsep-plugin/object": "^1.2.1", "@jsep-plugin/regex": "^1.0.3", "@jsep-plugin/template": "^1.0.2", - "blockly": "^6.20210701.0", + "blockly": "^9.2.0", "cronstrue": "^1.100.0", "dayjs": "^1.9.6", "dom7": "^2.1.5", @@ -2756,22 +2758,47 @@ } }, "node_modules/@blockly/field-slider": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.1.29.tgz", - "integrity": "sha512-LeWRhMhOhfuwVWoYpbtwovdMXlP48HRVULBz+a+DwqSIAv3qMArgJtYtPK1SDqOg4MBoqjUUdGkeFJeJ3arcfg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.3.tgz", + "integrity": "sha512-jbTEp4pHf+WG8eac3czUW+CvE+IKa8poZ97Jd3l+QPfeKuljWt9YYQ6x+7iOBx135kpHAZXUmPbQtRCjZA5oCw==", "engines": { "node": ">=8.0.0" + }, + "peerDependencies": { + "blockly": "^9.2.0" + } + }, + "node_modules/@blockly/plugin-cross-tab-copy-paste": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@blockly/plugin-cross-tab-copy-paste/-/plugin-cross-tab-copy-paste-2.0.4.tgz", + "integrity": "sha512-dznGTmY+wdUdFDhoAl9BK5c6TLXTa6u6W4t0I2oQq4oaJwXflY/lQraEmBTF7+1UTHsEBh2sOH9j2cHO6Xo2nA==", + "engines": { + "node": ">=8.17.0" + }, + "peerDependencies": { + "blockly": "^9.0.0" + } + }, + "node_modules/@blockly/theme-dark": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@blockly/theme-dark/-/theme-dark-4.0.1.tgz", + "integrity": "sha512-OIfdnt3kvPnEW/TmfLPUftcekwoQGmxg/12LajYUdW9aOLMQaen16Vw0+BB8Q8zKInpxT6JCBYECilYRLY+RpA==", + "engines": { + "node": ">=8.17.0" + }, + "peerDependencies": { + "blockly": "^9.0.0" } }, "node_modules/@blockly/zoom-to-fit": { - "version": "2.0.24", - "resolved": "https://registry.npmjs.org/@blockly/zoom-to-fit/-/zoom-to-fit-2.0.24.tgz", - "integrity": "sha512-dbcCjyrH7cgwsLE1e/7Hfh42RN1J0CCGni5/7JgeztpR6POfSlQU7rkElxw4qf9HEkHtJa/qBk0l+VB4lqxDgA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@blockly/zoom-to-fit/-/zoom-to-fit-3.0.3.tgz", + "integrity": "sha512-I2LWSRcJfIpz9GC98tuaJe9ZJcTDa+Brq473cq0WuC3+JWFH5SmfWwriD5dtSL7jXKL5RnQmzXmlczL+T8AaGA==", "engines": { "node": ">=8.17.0" }, "peerDependencies": { - "blockly": ">=6.20210701.0 <9" + "blockly": "^9.0.0" } }, "node_modules/@bundle-stats/utils": { @@ -3802,6 +3829,14 @@ "node": ">= 8" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@types/babel__core": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", @@ -4343,6 +4378,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, "dependencies": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" @@ -4384,6 +4420,17 @@ "pkcs7": "^1.0.4" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -4410,6 +4457,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4559,7 +4607,8 @@ "node_modules/array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, "node_modules/array-find": { "version": "1.0.0", @@ -4757,6 +4806,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -4793,6 +4843,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, "engines": { "node": ">=0.8" } @@ -4908,6 +4959,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, "engines": { "node": "*" } @@ -4915,7 +4967,8 @@ "node_modules/aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true }, "node_modules/babel-code-frame": { "version": "6.26.0", @@ -5492,6 +5545,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -5524,18 +5578,17 @@ } }, "node_modules/blockly": { - "version": "6.20210701.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-6.20210701.0.tgz", - "integrity": "sha512-cNrwFOAxXE5Pbs1FJAyLTlSRzpNW/C+0gPT2rGQDOJVVKcyF3vhFC1StgnxvQNsv//ueuksKWIXxDuSWh1VI4w==", - "license": "Apache-2.0", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-9.2.0.tgz", + "integrity": "sha512-rygZJupS5u4DMGGQ70gExH71c34vUEUjTVVBzhgVH7PCAK2RaitCNwr2yF6hGj/QTVodkjjEOdTzbHqLbuPipQ==", "dependencies": { - "jsdom": "15.2.1" + "jsdom": "20.0.3" } }, "node_modules/blockly/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "bin": { "acorn": "bin/acorn" }, @@ -5543,10 +5596,27 @@ "node": ">=0.4.0" } }, + "node_modules/blockly/node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/blockly/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/blockly/node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, "node_modules/blockly/node_modules/cssstyle": { "version": "2.3.0", @@ -5564,81 +5634,247 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, - "node_modules/blockly/node_modules/jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "node_modules/blockly/node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", "dependencies": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", - "xml-name-validator": "^3.0.0" + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/blockly/node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + "node_modules/blockly/node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/blockly/node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/blockly/node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/blockly/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/blockly/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/blockly/node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/blockly/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/blockly/node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } }, "node_modules/blockly/node_modules/parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/blockly/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/blockly/node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { "node": ">=6" } }, + "node_modules/blockly/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/blockly/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/blockly/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/blockly/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/blockly/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } + }, "node_modules/blockly/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/blockly/node_modules/ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", @@ -5653,6 +5889,14 @@ } } }, + "node_modules/blockly/node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "engines": { + "node": ">=12" + } + }, "node_modules/bluebird": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", @@ -5805,7 +6049,8 @@ "node_modules/browser-process-hrtime": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true }, "node_modules/browser-resolve": { "version": "1.11.3", @@ -6174,7 +6419,8 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "node_modules/chalk": { "version": "2.4.2", @@ -7998,6 +8244,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -8009,6 +8256,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, "dependencies": { "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", @@ -8019,6 +8267,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -8094,6 +8343,11 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", @@ -8513,6 +8767,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, "dependencies": { "webidl-conversions": "^4.0.2" } @@ -8588,6 +8843,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -8845,6 +9101,7 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "dev": true, "dependencies": { "esprima": "^3.1.3", "estraverse": "^4.2.0", @@ -8866,6 +9123,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -8878,6 +9136,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "optional": true, "engines": { "node": ">=0.10.0" @@ -10181,7 +10440,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -10218,6 +10476,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -10551,7 +10810,8 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "node_modules/extend-shallow": { "version": "3.0.2", @@ -10715,6 +10975,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, "engines": [ "node >=0.6.0" ] @@ -10727,7 +10988,8 @@ "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -11064,6 +11326,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, "engines": { "node": "*" } @@ -11072,6 +11335,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -11297,6 +11561,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -11489,6 +11754,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, "engines": { "node": ">=4" } @@ -11497,6 +11763,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, "dependencies": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -11738,6 +12005,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, "dependencies": { "whatwg-encoding": "^1.0.1" } @@ -11928,6 +12196,19 @@ "node": ">=8.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-proxy-middleware": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", @@ -11947,6 +12228,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -11963,6 +12245,18 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -11976,6 +12270,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -12182,6 +12477,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, "engines": { "node": ">=4" } @@ -12543,6 +12839,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, "node_modules/is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -12620,7 +12921,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "node_modules/is-whitespace": { "version": "0.3.0", @@ -12694,7 +12996,8 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "2.0.5", @@ -13048,6 +13351,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -13514,7 +13818,8 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true }, "node_modules/jsdom": { "version": "11.12.0", @@ -13605,12 +13910,14 @@ "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify": { "version": "1.0.1", @@ -13630,7 +13937,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "node_modules/json3": { "version": "3.3.3", @@ -13678,6 +13986,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "engines": [ "node >=0.6.0" ], @@ -14421,7 +14730,8 @@ "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true }, "node_modules/lodash.support": { "version": "2.3.0", @@ -15418,15 +15728,15 @@ } }, "node_modules/nwsapi": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", - "dev": true + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, "engines": { "node": "*" } @@ -16169,7 +16479,8 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "node_modules/picocolors": { "version": "0.2.1", @@ -16368,7 +16679,8 @@ "node_modules/pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true }, "node_modules/pngjs": { "version": "3.4.0", @@ -17802,6 +18114,7 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, "engines": { "node": ">=0.6" } @@ -17842,8 +18155,7 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "node_modules/railroad-diagrams": { "version": "1.0.0", @@ -18309,6 +18621,7 @@ "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -18348,6 +18661,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, "dependencies": { "lodash": "^4.17.11" }, @@ -18359,6 +18673,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, "dependencies": { "request-promise-core": "1.1.2", "stealthy-require": "^1.1.1", @@ -18436,8 +18751,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "node_modules/resize-detector": { "version": "0.1.10", @@ -18701,14 +19015,14 @@ "dev": true }, "node_modules/saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dependencies": { - "xmlchars": "^2.1.1" + "xmlchars": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=v12.22.7" } }, "node_modules/schema-utils": { @@ -19533,6 +19847,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -19949,6 +20264,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -21215,6 +21531,7 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, "dependencies": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -21226,12 +21543,14 @@ "node_modules/tough-cookie/node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true }, "node_modules/tr46": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -21288,6 +21607,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -21298,7 +21618,8 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true }, "node_modules/type-check": { "version": "0.3.2", @@ -21681,6 +22002,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -21719,7 +22041,6 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -21788,6 +22109,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true, "bin": { "uuid": "bin/uuid" } @@ -21832,6 +22154,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "engines": [ "node >=0.6.0" ], @@ -22160,18 +22483,28 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, "dependencies": { "browser-process-hrtime": "^0.1.2" } }, "node_modules/w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dependencies": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "engines": { + "node": ">=12" } }, "node_modules/walker": { @@ -22243,6 +22576,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -22338,7 +22672,8 @@ "node_modules/webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true }, "node_modules/webpack": { "version": "4.46.0", @@ -22776,6 +23111,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -23085,6 +23421,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, "dependencies": { "iconv-lite": "0.4.24" } @@ -23098,7 +23435,8 @@ "node_modules/whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true }, "node_modules/whatwg-url": { "version": "6.5.0", @@ -23391,7 +23729,8 @@ "node_modules/xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true }, "node_modules/xmlchars": { "version": "2.2.0", @@ -26194,14 +26533,27 @@ } }, "@blockly/field-slider": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-2.1.29.tgz", - "integrity": "sha512-LeWRhMhOhfuwVWoYpbtwovdMXlP48HRVULBz+a+DwqSIAv3qMArgJtYtPK1SDqOg4MBoqjUUdGkeFJeJ3arcfg==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.3.tgz", + "integrity": "sha512-jbTEp4pHf+WG8eac3czUW+CvE+IKa8poZ97Jd3l+QPfeKuljWt9YYQ6x+7iOBx135kpHAZXUmPbQtRCjZA5oCw==", + "requires": {} + }, + "@blockly/plugin-cross-tab-copy-paste": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@blockly/plugin-cross-tab-copy-paste/-/plugin-cross-tab-copy-paste-2.0.4.tgz", + "integrity": "sha512-dznGTmY+wdUdFDhoAl9BK5c6TLXTa6u6W4t0I2oQq4oaJwXflY/lQraEmBTF7+1UTHsEBh2sOH9j2cHO6Xo2nA==", + "requires": {} + }, + "@blockly/theme-dark": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@blockly/theme-dark/-/theme-dark-4.0.1.tgz", + "integrity": "sha512-OIfdnt3kvPnEW/TmfLPUftcekwoQGmxg/12LajYUdW9aOLMQaen16Vw0+BB8Q8zKInpxT6JCBYECilYRLY+RpA==", + "requires": {} }, "@blockly/zoom-to-fit": { - "version": "2.0.24", - "resolved": "https://registry.npmjs.org/@blockly/zoom-to-fit/-/zoom-to-fit-2.0.24.tgz", - "integrity": "sha512-dbcCjyrH7cgwsLE1e/7Hfh42RN1J0CCGni5/7JgeztpR6POfSlQU7rkElxw4qf9HEkHtJa/qBk0l+VB4lqxDgA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@blockly/zoom-to-fit/-/zoom-to-fit-3.0.3.tgz", + "integrity": "sha512-I2LWSRcJfIpz9GC98tuaJe9ZJcTDa+Brq473cq0WuC3+JWFH5SmfWwriD5dtSL7jXKL5RnQmzXmlczL+T8AaGA==", "requires": {} }, "@bundle-stats/utils": { @@ -27046,6 +27398,11 @@ } } }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + }, "@types/babel__core": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", @@ -27566,6 +27923,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" @@ -27601,6 +27959,14 @@ "pkcs7": "^1.0.4" } }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -27623,6 +27989,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -27741,7 +28108,8 @@ "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, "array-find": { "version": "1.0.0", @@ -27902,6 +28270,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -27956,7 +28325,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "assign-symbols": { "version": "1.0.0", @@ -28034,12 +28404,14 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true }, "babel-code-frame": { "version": "6.26.0", @@ -28540,6 +28912,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -28566,22 +28939,36 @@ } }, "blockly": { - "version": "6.20210701.0", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-6.20210701.0.tgz", - "integrity": "sha512-cNrwFOAxXE5Pbs1FJAyLTlSRzpNW/C+0gPT2rGQDOJVVKcyF3vhFC1StgnxvQNsv//ueuksKWIXxDuSWh1VI4w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-9.2.0.tgz", + "integrity": "sha512-rygZJupS5u4DMGGQ70gExH71c34vUEUjTVVBzhgVH7PCAK2RaitCNwr2yF6hGj/QTVodkjjEOdTzbHqLbuPipQ==", "requires": { - "jsdom": "15.2.1" + "jsdom": "20.0.3" }, "dependencies": { "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, "cssstyle": { "version": "2.3.0", @@ -28598,74 +28985,180 @@ } } }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "requires": { + "webidl-conversions": "^7.0.0" + } + }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", - "requires": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", - "xml-name-validator": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + } }, "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true }, "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", "punycode": "^2.1.1" } }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + }, "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" } }, "ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" } } }, @@ -28808,7 +29301,8 @@ "browser-process-hrtime": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true }, "browser-resolve": { "version": "1.11.3", @@ -29152,7 +29646,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "chalk": { "version": "2.4.2", @@ -30622,6 +31117,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -30630,6 +31126,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, "requires": { "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", @@ -30640,6 +31137,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -30701,6 +31199,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, "decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", @@ -31064,6 +31567,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, "requires": { "webidl-conversions": "^4.0.2" } @@ -31132,6 +31636,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -31363,6 +31868,7 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "dev": true, "requires": { "esprima": "^3.1.3", "estraverse": "^4.2.0", @@ -31374,12 +31880,14 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "optional": true } } @@ -32424,8 +32932,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", @@ -32448,7 +32955,8 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true }, "esutils": { "version": "2.0.2", @@ -32714,7 +33222,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "3.0.2", @@ -32852,7 +33361,8 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "fast-deep-equal": { "version": "3.1.3", @@ -32862,7 +33372,8 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -33134,12 +33645,14 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -33324,6 +33837,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -33475,12 +33989,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -33686,6 +34202,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, "requires": { "whatwg-encoding": "^1.0.1" } @@ -33855,6 +34372,16 @@ "requires-port": "^1.0.0" } }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, "http-proxy-middleware": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", @@ -33871,6 +34398,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -33883,6 +34411,15 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -33893,6 +34430,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -34061,7 +34599,8 @@ "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true }, "ipaddr.js": { "version": "1.9.1", @@ -34340,6 +34879,11 @@ "isobject": "^3.0.1" } }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -34399,7 +34943,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-whitespace": { "version": "0.3.0", @@ -34458,7 +35003,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -35122,7 +35668,8 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true }, "jsdom": { "version": "11.12.0", @@ -35200,12 +35747,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify": { "version": "1.0.1", @@ -35225,7 +35774,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json3": { "version": "3.3.3", @@ -35269,6 +35819,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -35899,7 +36450,8 @@ "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true }, "lodash.support": { "version": "2.3.0", @@ -36746,15 +37298,15 @@ "dev": true }, "nwsapi": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", - "dev": true + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -37340,7 +37892,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "picocolors": { "version": "0.2.1", @@ -37493,7 +38046,8 @@ "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true }, "pngjs": { "version": "3.4.0", @@ -38674,7 +39228,8 @@ "qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true }, "query-string": { "version": "6.14.1", @@ -38703,8 +39258,7 @@ "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "railroad-diagrams": { "version": "1.0.0", @@ -39085,6 +39639,7 @@ "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -39121,6 +39676,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, "requires": { "lodash": "^4.17.11" } @@ -39129,6 +39685,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, "requires": { "request-promise-core": "1.1.2", "stealthy-require": "^1.1.1", @@ -39187,8 +39744,7 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "resize-detector": { "version": "0.1.10", @@ -39412,11 +39968,11 @@ "dev": true }, "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "requires": { - "xmlchars": "^2.1.1" + "xmlchars": "^2.2.0" } }, "schema-utils": { @@ -40124,6 +40680,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -40475,7 +41032,8 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true }, "stream-browserify": { "version": "2.0.2", @@ -41519,6 +42077,7 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -41527,7 +42086,8 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true } } }, @@ -41535,6 +42095,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -41590,6 +42151,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -41597,7 +42159,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true }, "type-check": { "version": "0.3.2", @@ -41915,6 +42478,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -41958,7 +42522,6 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -42014,7 +42577,8 @@ "uuid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true }, "v-clipboard": { "version": "2.2.3", @@ -42053,6 +42617,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -42344,18 +42909,24 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, "requires": { "browser-process-hrtime": "^0.1.2" } }, "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" + "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==" + } } }, "walker": { @@ -42505,7 +43076,8 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true }, "webpack": { "version": "4.46.0", @@ -43094,6 +43666,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, "requires": { "iconv-lite": "0.4.24" } @@ -43107,7 +43680,8 @@ "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true }, "whatwg-url": { "version": "6.5.0", @@ -43378,7 +43952,8 @@ "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true }, "xmlchars": { "version": "2.2.0", diff --git a/bundles/org.openhab.ui/web/package.json b/bundles/org.openhab.ui/web/package.json index b332958b3c..9be0ce9044 100644 --- a/bundles/org.openhab.ui/web/package.json +++ b/bundles/org.openhab.ui/web/package.json @@ -61,13 +61,15 @@ "Samsung >= 5" ], "dependencies": { - "@blockly/field-slider": "^2.1.10", - "@blockly/zoom-to-fit": "^2.0.24", + "@blockly/field-slider": "^4.0.3", + "@blockly/plugin-cross-tab-copy-paste": "^2.0.4", + "@blockly/theme-dark": "^4.0.1", + "@blockly/zoom-to-fit": "^3.0.3", "@jsep-plugin/arrow": "^1.0.5", "@jsep-plugin/object": "^1.2.1", "@jsep-plugin/regex": "^1.0.3", "@jsep-plugin/template": "^1.0.2", - "blockly": "^6.20210701.0", + "blockly": "^9.2.0", "cronstrue": "^1.100.0", "dayjs": "^1.9.6", "dom7": "^2.1.5", diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-exec.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-exec.js index b2230020b2..782417fb02 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-exec.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-exec.js @@ -1,4 +1,5 @@ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldItemModelPicker } from './ohitemfield' export default function defineOHBlocks_Exec (f7) { @@ -22,9 +23,9 @@ export default function defineOHBlocks_Exec (f7) { } } - Blockly.JavaScript['oh_exec'] = function (block) { + javascriptGenerator['oh_exec'] = function (block) { let runCommand = block.getFieldValue('execCommand') - const itemName = Blockly.JavaScript.valueToCode(block, 'sendTo', Blockly.JavaScript.ORDER_ATOMIC) + const itemName = javascriptGenerator.valueToCode(block, 'sendTo', javascriptGenerator.ORDER_ATOMIC) let code = 'var exec = Java.type("org.openhab.core.model.script.actions.Exec");\n' code += 'var duration = Java.type("java.time.Duration");\n' code += 'var results = exec.executeCommandLine(duration.ofSeconds(1), "' + runCommand + '", "")\n' @@ -48,17 +49,17 @@ export default function defineOHBlocks_Exec (f7) { } } - Blockly.JavaScript['oh_exec2'] = function (block) { - const exec = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_exec2'] = function (block) { + const exec = javascriptGenerator.provideFunction_( 'exec', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Exec");']) - const duration = Blockly.JavaScript.provideFunction_( + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Exec");']) + const duration = javascriptGenerator.provideFunction_( 'duration', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.Duration");']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.Duration");']) let runCommand = block.getFieldValue('cmdExecute').replace(/ /g, '","') let timeout = block.getFieldValue('timeout') let code = exec + '.executeCommandLine(' + duration + '.ofSeconds(' + timeout + '),"' + runCommand + '")\n' - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } Blockly.Blocks['oh_exec3'] = { @@ -78,16 +79,16 @@ export default function defineOHBlocks_Exec (f7) { } } - Blockly.JavaScript['oh_exec3'] = function (block) { - const exec = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_exec3'] = function (block) { + const exec = javascriptGenerator.provideFunction_( 'exec', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Exec\');']) - const duration = Blockly.JavaScript.provideFunction_( + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Exec\');']) + const duration = javascriptGenerator.provideFunction_( 'duration', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.time.Duration\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.time.Duration\');']) let runCommand = block.getFieldValue('cmdExecute').replace(/ /g, '","') let timeout = block.getFieldValue('timeout') let code = exec + '.executeCommandLine(' + duration + '.ofSeconds(' + timeout + '),"' + runCommand + '")\n' - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-http.js index 4065a580ca..797f14ce67 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/_tmp/blocks-http.js @@ -1,4 +1,5 @@ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldItemModelPicker } from './ohitemfield' export default function defineOHBlocks_HTTP (f7, scripts) { @@ -22,21 +23,21 @@ export default function defineOHBlocks_HTTP (f7, scripts) { } } - Blockly.JavaScript['oh_httprequest'] = function (block) { - const http = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_httprequest'] = function (block) { + const http = javascriptGenerator.provideFunction_( 'http', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.HTTP\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.HTTP\');']) let requesttype = block.getFieldValue('requestType') let contenttype = block.getFieldValue('contentType') - let url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC) - let payload = Blockly.JavaScript.valueToCode(block, 'payload', Blockly.JavaScript.ORDER_ATOMIC) + let url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) + let payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) let code = '' if (contenttype === 'none') { code = http + '.' + requesttype + '("' + url + '",60)' } else { code = http + '.' + requesttype + '(' + url + ',"' + contenttype + '","' + payload + '")' } - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } Blockly.Blocks['oh_script_dropdown'] = { @@ -58,10 +59,10 @@ export default function defineOHBlocks_HTTP (f7, scripts) { } } - Blockly.JavaScript['oh_script_dropdown'] = function (block) { + javascriptGenerator['oh_script_dropdown'] = function (block) { let scriptName = block.getFieldValue('script') let code = scriptName - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } Blockly.Blocks['oh_ping'] = { @@ -76,12 +77,12 @@ export default function defineOHBlocks_HTTP (f7, scripts) { } } - Blockly.JavaScript['oh_ping'] = function (block) { - const actions = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_ping'] = function (block) { + const actions = javascriptGenerator.provideFunction_( 'actions', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Ping");']) - let hostname = Blockly.JavaScript.valueToCode(block, 'hostName', Blockly.JavaScript.ORDER_ATOMIC) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Ping");']) + let hostname = javascriptGenerator.valueToCode(block, 'hostName', javascriptGenerator.ORDER_ATOMIC) let code = actions + '.checkVitality(' + hostname + ',0,10)' - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-audio.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-audio.js index 9f25956f91..da23f02e2b 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-audio.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-audio.js @@ -6,12 +6,15 @@ * - Even though "enhancedjavasound" is provided as a sink, currently it is not clear what the intention is * * See more background info on openHAB multimedia here: https://www.openhab.org/docs/configuration/multimedia.html +* +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldSlider } from '@blockly/field-slider' -export default function (f7, sinks, voices) { +export default function (f7, isGraalJs, sinks, voices) { Blockly.Blocks['oh_volumeslider'] = { init: function () { this.appendDummyInput() @@ -22,7 +25,7 @@ export default function (f7, sinks, voices) { } } - Blockly.JavaScript['oh_volumeslider'] = function (block) { + javascriptGenerator['oh_volumeslider'] = function (block) { const fieldName = block.getFieldValue('volume') let code = `'${fieldName}'` return [code, 0] @@ -53,13 +56,12 @@ export default function (f7, sinks, voices) { * Plays a file (like mp3) which resides in conf/sounds to the given sink * Code part */ - Blockly.JavaScript['oh_playmedia_sink'] = function (block) { - const audio = addAudio() - let fileName = Blockly.JavaScript.valueToCode(block, 'fileName', Blockly.JavaScript.ORDER_ATOMIC) - let sinkName = Blockly.JavaScript.valueToCode(block, 'sinkName', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') + javascriptGenerator['oh_playmedia_sink'] = function (block) { + let fileName = javascriptGenerator.valueToCode(block, 'fileName', javascriptGenerator.ORDER_ATOMIC) + let sinkName = javascriptGenerator.valueToCode(block, 'sinkName', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - let code = `${audio}.playSound(${sinkName}, ${fileName});\n` - return code + const audio = (isGraalJs) ? 'actions.Audio' : addAudio() + return `${audio}.playSound(${sinkName}, ${fileName});\n` } /* @@ -91,14 +93,17 @@ export default function (f7, sinks, voices) { * Note: In general, though more complex, rather create a volume item for that device and set the volume first as it is more reliable. * Code part */ - Blockly.JavaScript['oh_playmedia_sink_volume'] = function (block) { - const audio = addAudio() - let fileName = Blockly.JavaScript.valueToCode(block, 'fileName', Blockly.JavaScript.ORDER_ATOMIC) - let sinkName = Blockly.JavaScript.valueToCode(block, 'sinkName', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - let volume = Blockly.JavaScript.valueToCode(block, 'volume', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, '') + javascriptGenerator['oh_playmedia_sink_volume'] = function (block) { + let fileName = javascriptGenerator.valueToCode(block, 'fileName', javascriptGenerator.ORDER_ATOMIC) + let sinkName = javascriptGenerator.valueToCode(block, 'sinkName', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') + let volume = javascriptGenerator.valueToCode(block, 'volume', javascriptGenerator.ORDER_ATOMIC).replace(/'/g, '') - let code = `${audio}.playSound(${sinkName}, ${fileName}, new PercentType(${volume}));\n` - return code + if (isGraalJs) { + return `actions.Audio.playSound(${sinkName}, ${fileName}, new runtime.PercentType(${volume}));\n` + } else { + const audio = addAudio() + return `${audio}.playSound(${sinkName}, ${fileName}, new PercentType(${volume}));\n` + } } /* @@ -126,12 +131,12 @@ export default function (f7, sinks, voices) { * Plays a stream from a URL on a specific sink * Blockly part */ - Blockly.JavaScript['oh_playstream_sink'] = function (block) { - const audio = addAudio() - let url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC) - let sinkName = Blockly.JavaScript.valueToCode(block, 'sinkName', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - let code = `${audio}.playStream(${sinkName}, ${url});\n` - return code + javascriptGenerator['oh_playstream_sink'] = function (block) { + let url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) + let sinkName = javascriptGenerator.valueToCode(block, 'sinkName', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') + + const audio = (isGraalJs) ? 'actions.Audio' : addAudio() + return `${audio}.playStream(${sinkName}, ${url});\n` } /* @@ -156,12 +161,12 @@ export default function (f7, sinks, voices) { * Stops a stream on a specific sink * Blockly part */ - Blockly.JavaScript['oh_stopstream_sink'] = function (block) { - const audio = addAudio() + javascriptGenerator['oh_stopstream_sink'] = function (block) { let url = block.getFieldValue('url') - let sinkName = Blockly.JavaScript.valueToCode(block, 'sinkName', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - let code = `${audio}.playStream(${sinkName}, null);\n` - return code + let sinkName = javascriptGenerator.valueToCode(block, 'sinkName', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') + + const audio = (isGraalJs) ? 'actions.Audio' : addAudio() + return `${audio}.playStream(${sinkName}, null);\n` } /* @@ -191,17 +196,13 @@ export default function (f7, sinks, voices) { * Says some text via a device sink - TTS has to be installed for that * Code part */ - Blockly.JavaScript['oh_say'] = function (block) { - const voice = Blockly.JavaScript.provideFunction_( - 'voice', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Voice\');']) + javascriptGenerator['oh_say'] = function (block) { + const textToSay = javascriptGenerator.valueToCode(block, 'textToSay', javascriptGenerator.ORDER_ATOMIC) + const voiceName = javascriptGenerator.valueToCode(block, 'voice', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') + const deviceSink = javascriptGenerator.valueToCode(block, 'deviceSink', javascriptGenerator.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - const textToSay = Blockly.JavaScript.valueToCode(block, 'textToSay', Blockly.JavaScript.ORDER_ATOMIC) - const voiceName = Blockly.JavaScript.valueToCode(block, 'voice', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - const deviceSink = Blockly.JavaScript.valueToCode(block, 'deviceSink', Blockly.JavaScript.ORDER_ATOMIC).replace('(', '').replace(/[()]/g, '') - - const code = `${voice}.say(${textToSay}, ${voiceName}, ${deviceSink});\n` - return code + const voice = (isGraalJs) ? 'actions.Voice' : addVoice() + return `${voice}.say(${textToSay}, ${voiceName}, ${deviceSink});\n` } /* @@ -228,9 +229,9 @@ export default function (f7, sinks, voices) { } } - Blockly.JavaScript['oh_audiosink_dropdown'] = function (block) { + javascriptGenerator['oh_audiosink_dropdown'] = function (block) { let sinkName = block.getFieldValue('sinks') - return [`'${sinkName}'`, Blockly.JavaScript.ORDER_NONE] + return [`'${sinkName}'`, javascriptGenerator.ORDER_NONE] } /* @@ -258,14 +259,20 @@ export default function (f7, sinks, voices) { } } - Blockly.JavaScript['oh_voices_dropdown'] = function (block) { + javascriptGenerator['oh_voices_dropdown'] = function (block) { let voiceName = block.getFieldValue('voiceName') - return [`'${voiceName}'`, Blockly.JavaScript.ORDER_NONE] + return [`'${voiceName}'`, javascriptGenerator.ORDER_NONE] } function addAudio () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'audio', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Audio\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Audio\');']) + } + + function addVoice () { + return javascriptGenerator.provideFunction_( + 'voice', + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.Voice\');']) } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-color.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-color.js index 4eabf6f59c..f4224ae219 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-color.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-color.js @@ -1,10 +1,12 @@ /* * Adds new blocks to the colour section +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { /* * converts a hex color string in to an openHAB hue-saturation-brightness string * Block @@ -26,9 +28,9 @@ export default function (f7) { * converts a hex color string in to an openHAB hue-saturation-brightness string * Code generation */ - Blockly.JavaScript['oh_color_to_hsb'] = function (block) { + javascriptGenerator['oh_color_to_hsb'] = function (block) { let conversionFunction = addConvertColourHexToHSB() - const hexColor = Blockly.JavaScript.valueToCode(block, 'hexColor', Blockly.JavaScript.ORDER_ATOMIC) + const hexColor = javascriptGenerator.valueToCode(block, 'hexColor', javascriptGenerator.ORDER_ATOMIC) let code = `${conversionFunction}(${hexColor})` return [code, 0] } @@ -37,10 +39,10 @@ export default function (f7) { * converts rgb to hsb (thanks to https://www.30secondsofcode.org/js/s/rgb-to-hsb) */ function addConvertColourHexToHSB () { - const hsbConversion = Blockly.JavaScript.provideFunction_( + const hsbConversion = javascriptGenerator.provideFunction_( 'colorHexToHSB', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' (hexColor) {', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' (hexColor) {', ' var rgb = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hexColor);', ' if (!rgb) return \'\';', ' var r = parseInt(rgb[1], 16) / 255, g = parseInt(rgb[2], 16) / 255, b = parseInt(rgb[3], 16) / 255;', diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js index 57a729ca4c..946e9d198c 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js @@ -1,8 +1,12 @@ +/** + * supports jsscripting + */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldDatePicker } from './fields/date-field' -import { addDateSupport, addDateComparisonSupport, addGetZdtComponent, addChrono } from './utils' +import { addDateSupport, addDateComparisonSupportNashorn, addDateComparisonSupportGraalVM, addGetZdtComponent, addChrono } from './utils' -export default function (f7) { +export default function (f7, isGraalJs) { /* * Typed (DayOffset) block that can be used with the Ephemeris check block * Note that the block basically returns a zero day offset for the check @@ -23,9 +27,9 @@ export default function (f7) { * Typed block that can be used with Ephemeris check block * Code part */ - Blockly.JavaScript['oh_dayoffset_today'] = function (block) { + javascriptGenerator['oh_dayoffset_today'] = function (block) { let code = '0' - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } /* @@ -50,10 +54,10 @@ export default function (f7) { * Typed (DayOffset) block with a day positve or negative offset * Code part */ - Blockly.JavaScript['oh_dayoffset'] = function (block) { - let offsetValue = Blockly.JavaScript.valueToCode(block, 'offset', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_dayoffset'] = function (block) { + let offsetValue = javascriptGenerator.valueToCode(block, 'offset', javascriptGenerator.ORDER_ATOMIC) let code = `${offsetValue}` - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } /* @@ -75,10 +79,9 @@ export default function (f7) { * Typed (DayOffset) block with a day positve or negative offset that can be used with the Ephemeris check block * Code part */ - Blockly.JavaScript['oh_zdt_now'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - let code = `${zdt}.now()` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt_now'] = function (block) { + const zdt = (isGraalJs) ? 'time.ZonedDateTime' : addDateSupport()[1] + return [`${zdt}.now()`, javascriptGenerator.ORDER_NONE] } /* @@ -109,13 +112,13 @@ export default function (f7) { * Typed (DayOffset) block with a day positve or negative offset that can be used with the Ephemeris check block * Code part */ - Blockly.JavaScript['oh_zdt_plusminus'] = function (block) { - let [dtf, zdt, getZonedDatetime] = addDateSupport() - let offsetValue = Blockly.JavaScript.valueToCode(block, 'offset', Blockly.JavaScript.ORDER_ATOMIC) - let plusMinus = block.getFieldValue('plusminus') - let period = block.getFieldValue('period') - let code = `${zdt}.now().${plusMinus}${period}(${offsetValue})` - return [code, Blockly.JavaScript.ORDER_ATOMIC] + javascriptGenerator['oh_zdt_plusminus'] = function (block) { + const offsetValue = javascriptGenerator.valueToCode(block, 'offset', javascriptGenerator.ORDER_ATOMIC) + const plusMinus = block.getFieldValue('plusminus') + const period = block.getFieldValue('period') + + const zdt = (isGraalJs) ? 'time.ZonedDateTime' : addDateSupport()[1] + return [`${zdt}.now().${plusMinus}${period}(${offsetValue})`, javascriptGenerator.ORDER_ATOMIC] } /* @@ -157,18 +160,23 @@ export default function (f7) { * ZonedDateTime block with preset date and time * Code part */ - Blockly.JavaScript['oh_zdt_create'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - - let year = Blockly.JavaScript.valueToCode(block, 'year', Blockly.JavaScript.ORDER_ATOMIC) - let month = Blockly.JavaScript.valueToCode(block, 'month', Blockly.JavaScript.ORDER_ATOMIC) - let day = Blockly.JavaScript.valueToCode(block, 'day', Blockly.JavaScript.ORDER_ATOMIC) - let hour = Blockly.JavaScript.valueToCode(block, 'hour', Blockly.JavaScript.ORDER_ATOMIC) - let minute = Blockly.JavaScript.valueToCode(block, 'minute', Blockly.JavaScript.ORDER_ATOMIC) - let second = Blockly.JavaScript.valueToCode(block, 'second', Blockly.JavaScript.ORDER_ATOMIC) - - let code = `${czdt}(${year}, ${month} ,${day}, ${hour}, ${minute}, ${second}, 0, ${zdt}.now().getOffset().getId(), ${zdt}.now().getZone().getId())` - return [code, Blockly.JavaScript.ORDER_ATOMIC] + javascriptGenerator['oh_zdt_create'] = function (block) { + const year = javascriptGenerator.valueToCode(block, 'year', javascriptGenerator.ORDER_ATOMIC) + const month = javascriptGenerator.valueToCode(block, 'month', javascriptGenerator.ORDER_ATOMIC) + const day = javascriptGenerator.valueToCode(block, 'day', javascriptGenerator.ORDER_ATOMIC) + const hour = javascriptGenerator.valueToCode(block, 'hour', javascriptGenerator.ORDER_ATOMIC) + const minute = javascriptGenerator.valueToCode(block, 'minute', javascriptGenerator.ORDER_ATOMIC) + const second = javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_ATOMIC) + + if (isGraalJs) { + const code = `time.ZonedDateTime.now().withYear(${year}).withMonth(${month}).withDayOfMonth(${day}).withHour(${hour}).withMinute(${minute}).withSecond(${second}).withNano(0)` + return [code, javascriptGenerator.ORDER_ATOMIC] + } else { + let [dtf, zdt, gzdt, czdt] = addDateSupport() + let stringToParse = `${czdt}(${year}, ${month} ,${day}, ${hour}, ${minute}, ${second}, 0, ${zdt}.now().getOffset().getId(), ${zdt}.now().getZone().getId())` + let code = `${zdt}.parse(${stringToParse}, ${dtf}.ISO_ZONED_DATE_TIME)` + return [code, javascriptGenerator.ORDER_ATOMIC] + } } /* @@ -192,16 +200,15 @@ export default function (f7) { * Typed (ZonedDateTime) block that can be used with the Ephemeris check block * Code part */ - Blockly.JavaScript['oh_zdt'] = function (block) { - let [dtf, zdt, getZonedDateTime] = addDateSupport() - let day = block.getFieldValue('day') - let code = `${getZonedDateTime}('${day}')` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt'] = function (block) { + const day = block.getFieldValue('day') + const getZonedDateTime = (isGraalJs) ? 'time.toZDT' : addDateSupport()[2] + return [`${getZonedDateTime}('${day}')`, javascriptGenerator.ORDER_NONE] } /* * Typed (ZonedDateTime) block that can be used with the Ephemeris check block - * Allows input as string in the format format yyyy-MM-dd or yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss +HH:mm + * Allows input as string in the pattern yyyy-MM-dd or yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss +HH:mm * Blockly part */ Blockly.Blocks['oh_zdt_fromText'] = { @@ -235,23 +242,22 @@ export default function (f7) { * Typed (ZonedDateTime) block that can be used with the Ephemeris check block * Code part */ - Blockly.JavaScript['oh_zdt_fromText'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - let day = Blockly.JavaScript.valueToCode(block, 'day', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${gzdt}(${day})` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt_fromText'] = function (block) { + const day = javascriptGenerator.valueToCode(block, 'day', javascriptGenerator.ORDER_ATOMIC) + const getZonedDateTime = (isGraalJs) ? 'time.toZDT' : addDateSupport()[2] + return [`${getZonedDateTime}(${day})`, javascriptGenerator.ORDER_NONE] } /* * Typed (ZonedDateTime) block that can be used with the Ephemeris check block - * Allows input as string in the format format yyyy-MM-dd or yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss +HH:mm + * Allows input as string in the format yyyy-MM-dd or yyyy-MM-dd HH:mm:ss or yyyy-MM-dd HH:mm:ss +HH:mm * Blockly part */ Blockly.Blocks['oh_zdt_fromItem'] = { init: function () { this.appendValueInput('itemName') .appendField('datetime from item') - .setCheck('String') + .setCheck(['String', 'oh_item']) this.setOutput(true, 'ZonedDateTime') this.setColour(70) this.setTooltip('ZonedDateTime from a datetime item') @@ -263,11 +269,13 @@ export default function (f7) { * Typed (ZonedDateTime) block that can be used with the Ephemeris check block * Code part */ - Blockly.JavaScript['oh_zdt_fromItem'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - let itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) - let code = `itemRegistry.getItem(${itemName}).getState().getZonedDateTime()` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt_fromItem'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`time.toZDT(items.getItem(${itemName}))`, javascriptGenerator.ORDER_NONE] + } else { + return [`itemRegistry.getItem(${itemName}).getState().getZonedDateTime()`, javascriptGenerator.ORDER_NONE] + } } const nextImage = @@ -323,10 +331,9 @@ export default function (f7) { * A temporal unit that can be used to amend a ZonedDateTime * Code part */ - Blockly.JavaScript['oh_zdt_temporal_unit'] = function (block) { - let value = block.getFieldValue('value') - let code = `(${value})` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt_temporal_unit'] = function (block) { + const value = block.getFieldValue('value') + return [`(${value})`, javascriptGenerator.ORDER_NONE] } /* @@ -337,6 +344,8 @@ export default function (f7) { numberBlockInput: null, currentBlockType: 0, blockTypes: ['year', 'month', 'day', 'hour', 'minute', 'second', 'milli', 'micro', 'nano', 'day of year'], + // TODO: Set min values + // minValue: [0, 1, 1, 0, 0, 0, 0, 0, 0, 1], maxValue: [9999, 12, 31, 23, 59, 59, 999, 999, 999, 366], addNumberBlock: function () { if (this.workspace.id !== Blockly.getMainWorkspace().id) { @@ -397,11 +406,9 @@ export default function (f7) { * A temporal unit that can be used to amend a ZonedDateTime * Code part */ - Blockly.JavaScript['oh_zdt_temporal_unit_input'] = function (block) { - let value1 = Blockly.JavaScript.valueToCode(block, 'value', Blockly.JavaScript.ORDER_ATOMIC) - let value2 = block.getFieldValue('value') - let code = `(${value1})` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_zdt_temporal_unit_input'] = function (block) { + const value = javascriptGenerator.valueToCode(block, 'value', javascriptGenerator.ORDER_ATOMIC) + return [`(${value})`, javascriptGenerator.ORDER_NONE] } /* @@ -525,11 +532,10 @@ export default function (f7) { } } - Blockly.JavaScript['oh_zdt_amend'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - let chrono = addChrono() - let baseZdt = Blockly.JavaScript.valueToCode(block, 'baseZdt', Blockly.JavaScript.ORDER_ATOMIC) - let operation = block.getFieldValue('operation') + javascriptGenerator['oh_zdt_amend'] = function (block) { + const baseZdt = javascriptGenerator.valueToCode(block, 'baseZdt', javascriptGenerator.ORDER_ATOMIC) + const operation = block.getFieldValue('operation') + let code = baseZdt let millis = 0 let micros = 0 @@ -539,7 +545,7 @@ export default function (f7) { if (operationBlock) { let i for (i = 0; i < this.itemCount_; i++) { - let temporal = Blockly.JavaScript.valueToCode(block, 'ADD' + i, Blockly.JavaScript.ORDER_ATOMIC) + let temporal = javascriptGenerator.valueToCode(block, 'ADD' + i, javascriptGenerator.ORDER_ATOMIC) temporal = temporal.replace(/\(/g, '').replace(/\)/g, '') let inputBlock = this.getInputTargetBlock('ADD' + i) @@ -570,7 +576,7 @@ export default function (f7) { code += `.${operation}${operationUnit}(${totalNanos})` } } - return [code, Blockly.JavaScript.ORDER_ATOMIC] + return [code, javascriptGenerator.ORDER_ATOMIC] } Blockly.Blocks['oh_zdt_amend_container'] = { @@ -619,10 +625,10 @@ export default function (f7) { * Returns a string representation of an ephemeris date * Code part */ - Blockly.JavaScript['oh_zdt_toText'] = function (block) { - let [dtf, zdt, gzdt, czdt] = addDateSupport() - let date = Blockly.JavaScript.valueToCode(block, 'date', Blockly.JavaScript.ORDER_ATOMIC) - let withtime = block.getFieldValue('withtime') + javascriptGenerator['oh_zdt_toText'] = function (block) { + const date = javascriptGenerator.valueToCode(block, 'date', javascriptGenerator.ORDER_ATOMIC) + const withtime = block.getFieldValue('withtime') + const dtf = (isGraalJs) ? 'time.DateTimeFormatter' : addDateSupport()[0] let code = '' if (withtime === 'with') { @@ -633,7 +639,7 @@ export default function (f7) { code = `${date}.format(${dtf}.ofPattern('yyyy-MM-dd\\'T\\'HH:mm:ss.SSSZ'))` } - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } /* @@ -668,17 +674,15 @@ export default function (f7) { * Returns a string representation of an ephemeris date * Code part */ - Blockly.JavaScript['oh_zdt_compare'] = function (block) { - let zdtCompare = addDateComparisonSupport() - let zdtOne = Blockly.JavaScript.valueToCode(block, 'zdtOne', Blockly.JavaScript.ORDER_ATOMIC) - let zdtTwo = Blockly.JavaScript.valueToCode(block, 'zdtTwo', Blockly.JavaScript.ORDER_ATOMIC) - let operation = block.getFieldValue('operation') - let precision = block.getFieldValue('precision') - let dateComparison = block.getFieldValue('dateComparison') - - let code = `${zdtCompare}(${zdtOne}, ${zdtTwo}, '${operation}', '${precision}', '${dateComparison}')` + javascriptGenerator['oh_zdt_compare'] = function (block) { + const zdtOne = javascriptGenerator.valueToCode(block, 'zdtOne', javascriptGenerator.ORDER_ATOMIC) + const zdtTwo = javascriptGenerator.valueToCode(block, 'zdtTwo', javascriptGenerator.ORDER_ATOMIC) + const operation = block.getFieldValue('operation') + const precision = block.getFieldValue('precision') + const dateComparison = block.getFieldValue('dateComparison') - return [code, Blockly.JavaScript.ORDER_NONE] + const zdtCompare = (isGraalJs) ? addDateComparisonSupportGraalVM() : addDateComparisonSupportNashorn() + return [`${zdtCompare}(${zdtOne}, ${zdtTwo}, '${operation}', '${precision}', '${dateComparison}')`, javascriptGenerator.ORDER_NONE] } /* @@ -712,30 +716,34 @@ export default function (f7) { * Returns a string representation of an ephemeris date * Code part */ - Blockly.JavaScript['oh_zdt_between'] = function (block) { - let zdtCompare = addDateComparisonSupport() - let zdtOne = Blockly.JavaScript.valueToCode(block, 'zdtOne', Blockly.JavaScript.ORDER_ATOMIC) - let zdtTwo = Blockly.JavaScript.valueToCode(block, 'zdtTwo', Blockly.JavaScript.ORDER_ATOMIC) - let zdtThree = Blockly.JavaScript.valueToCode(block, 'zdtThree', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_zdt_between'] = function (block) { + let zdtCompare = addDateComparisonSupportNashorn() + let zdtOne = javascriptGenerator.valueToCode(block, 'zdtOne', javascriptGenerator.ORDER_ATOMIC) + let zdtTwo = javascriptGenerator.valueToCode(block, 'zdtTwo', javascriptGenerator.ORDER_ATOMIC) + let zdtThree = javascriptGenerator.valueToCode(block, 'zdtThree', javascriptGenerator.ORDER_ATOMIC) let dateComparison = block.getFieldValue('dateComparison') - let codeLow = `${zdtCompare}(${zdtTwo}, ${zdtOne}, 'beforeEqual', 'nanos', '${dateComparison}')` - let codeHigh = `${zdtCompare}(${zdtOne}, ${zdtThree}, 'beforeEqual', 'nanos', '${dateComparison}')` - let code = `(${codeLow} && ${codeHigh})` - return [code, Blockly.JavaScript.ORDER_NONE] + if (isGraalJs) { + const op = new Map([['dateandtime', 'isBetweenDateTimes'], ['date', 'isBetweenDates'], ['time', 'isBetweenTimes']]).get(dateComparison) + return [`${zdtOne}.${op}(${zdtTwo}, ${zdtThree})`, javascriptGenerator.ORDER_NONE] + } else { + let codeLow = `${zdtCompare}(${zdtTwo}, ${zdtOne}, 'beforeEqual', 'nanos', '${dateComparison}')` + let codeHigh = `${zdtCompare}(${zdtOne}, ${zdtThree}, 'beforeEqual', 'nanos', '${dateComparison}')` + let code = `(${codeLow} && ${codeHigh})` + return [code, javascriptGenerator.ORDER_NONE] + } } /* * Returns a temporal part of a zoned date time as a Number * Blockly part */ - Blockly.Blocks['oh_get_zdt_part'] = { init: function () { this.appendDummyInput() .appendField(new Blockly.FieldDropdown([['year', 'getYear'], ['month', 'getMonthValue'], ['day of month', 'getDayOfMonth'], ['day of week', 'getDayOfWeek'], ['day of year', 'getDayOfYear'], ['hour', 'getHour'], ['minute', 'getMinute'], ['second', 'getSecond'], ['milli', 'getMilli'], ['micro', 'getMicro'], ['nano', 'getNano']]), 'temporalPart') .appendField('of') - this.appendValueInput('date') + this.appendValueInput('zdt') .setCheck('ZonedDateTime') this.setInputsInline(true) this.setOutput(true, 'Number') @@ -746,30 +754,46 @@ export default function (f7) { } /* - * Returns a temporal part of a zoned date time as a Number + * Returns a temporal part of a ZonedDateTime as a Number * Code part */ - Blockly.JavaScript['oh_get_zdt_part'] = function (block) { - let getZdtComponent = addGetZdtComponent() - let chrono = addChrono() + javascriptGenerator['oh_get_zdt_part'] = function (block) { + const zdt = javascriptGenerator.valueToCode(block, 'zdt', javascriptGenerator.ORDER_ATOMIC) let temporalPart = block.getFieldValue('temporalPart') - switch (temporalPart) { - case 'getMilli': - temporalPart = `getLong(${chrono}.MILLI_OF_SECOND)` - break - case 'getMicro': - temporalPart = `getLong(${chrono}.MICRO_OF_SECOND) % 1000` - break - case 'getNano': - temporalPart = `getLong(${chrono}.NANO_OF_SECOND) % 1000` - break - default: - temporalPart += '()' - } - let date = Blockly.JavaScript.valueToCode(block, 'date', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${getZdtComponent}(${date}.${temporalPart})` - return [code, Blockly.JavaScript.ORDER_NONE] + if (isGraalJs) { + const op = new Map([['getYear', 'year'], ['getMonthValue', 'monthValue'], ['getDayOfMonth', 'dayOfMonth'], ['getDayOfWeek', 'dayOfWeek().value'], ['getDayOfYear', 'dayOfYear'], ['getHour', 'hour'], ['getMinute', 'minute'], ['getSecond', 'second'], ['getNano', 'nano']]) + switch (temporalPart) { + case 'getMilli': + temporalPart = 'getLong(time.ChronoField.MILLI_OF_SECOND)' + break + case 'getMicro': + temporalPart = 'getLong(time.ChronoField.MICRO_OF_SECOND) % 1000' + break + default: + temporalPart = op.get(temporalPart) + '()' + } + return [`${zdt}.${temporalPart}`, javascriptGenerator.ORDER_NONE] + } else { + const getZdtComponent = addGetZdtComponent() + const chrono = addChrono() + switch (temporalPart) { + case 'getMilli': + temporalPart = `getLong(${chrono}.MILLI_OF_SECOND)` + break + case 'getMicro': + temporalPart = `getLong(${chrono}.MICRO_OF_SECOND) % 1000` + break + case 'getNano': + temporalPart = `getLong(${chrono}.NANO_OF_SECOND) % 1000` + break + default: + temporalPart += '()' + } + + let code = `${getZdtComponent}(${zdt}.${temporalPart})` + return [code, javascriptGenerator.ORDER_NONE] + } } /* @@ -798,16 +822,16 @@ export default function (f7) { * Computes the number of temporal units between two zonedDateTimes * Code part */ - Blockly.JavaScript['oh_get_time_between'] = function (block) { - let chronoUnit = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_get_time_between'] = function (block) { + const temporalPart = block.getFieldValue('temporalPart') + const zdtOne = javascriptGenerator.valueToCode(block, 'zdtOne', javascriptGenerator.ORDER_ATOMIC) + const zdtTwo = javascriptGenerator.valueToCode(block, 'zdtTwo', javascriptGenerator.ORDER_ATOMIC) + + const chronoUnit = (isGraalJs) ? 'time.ChronoUnit' : javascriptGenerator.provideFunction_( 'chronoUnit', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.temporal.ChronoUnit");']) - let temporalPart = block.getFieldValue('temporalPart') - let divisor = '' + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.temporal.ChronoUnit");']) - let zdtOne = Blockly.JavaScript.valueToCode(block, 'zdtOne', Blockly.JavaScript.ORDER_ATOMIC) - let zdtTwo = Blockly.JavaScript.valueToCode(block, 'zdtTwo', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${chronoUnit}.${temporalPart}.between(${zdtOne},${zdtTwo})${divisor}` - return [code, Blockly.JavaScript.ORDER_NONE] + let code = `${chronoUnit}.${temporalPart}.between(${zdtOne},${zdtTwo})` + return [code, javascriptGenerator.ORDER_NONE] } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dicts.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dicts.js index b0fb72b246..2e3fe73957 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dicts.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dicts.js @@ -1,6 +1,11 @@ +/** + * supports jsscripting + */ + import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { Blockly.Blocks['dicts_create_with'] = { /** * Block for creating a list with any number of elements of any type. @@ -161,16 +166,16 @@ export default function (f7) { } } - Blockly.JavaScript['dicts_create_with'] = function (block) { + javascriptGenerator['dicts_create_with'] = function (block) { // Create an object with any number of elements of any type. let elements = new Array(block.itemCount_) for (let i = 0; i < block.itemCount_; i++) { elements[i] = '\'' + block.getFieldValue('KEY' + i) + '\': ' - elements[i] += Blockly.JavaScript.valueToCode(block, 'ADD' + i, - Blockly.JavaScript.ORDER_NONE) || 'null' + elements[i] += javascriptGenerator.valueToCode(block, 'ADD' + i, + javascriptGenerator.ORDER_NONE) || 'null' } let code = '{' + elements.join(', ') + '}' - return [code, Blockly.JavaScript.ORDER_ATOMIC] + return [code, javascriptGenerator.ORDER_ATOMIC] } /* @@ -197,9 +202,9 @@ export default function (f7) { * Allows retrieving parameters provided by a rule * Code part */ - Blockly.JavaScript['dicts_get'] = function (block) { - const key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC) - const varName = Blockly.JavaScript.valueToCode(block, 'varName', Blockly.JavaScript.ORDER_ATOMIC).replace(/'/g, '') + javascriptGenerator['dicts_get'] = function (block) { + const key = javascriptGenerator.valueToCode(block, 'key', javascriptGenerator.ORDER_ATOMIC) + const varName = javascriptGenerator.valueToCode(block, 'varName', javascriptGenerator.ORDER_ATOMIC).replace(/'/g, '') let code = `${varName}[${key}]` return [code, 0] } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-ephemeris.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-ephemeris.js index ecdb2bb1a9..daa25451c5 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-ephemeris.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-ephemeris.js @@ -4,11 +4,12 @@ * * See more background info on openHAB ephemeris here: https://www.openhab.org/docs/configuration/actions.html#ephemeris * See usage discussion here: https://community.openhab.org/t/wip-ephemeris-documentation/84536 +* supports jsscripting */ import Blockly from 'blockly' -import { FieldDatePicker } from './fields/date-field' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { /* * Checks if the provided day is a * - bank holiday (needs to be configured in openHAB @@ -36,11 +37,10 @@ export default function (f7) { * Checks if the provided day is a bank holiday, weekend or weekday * Code part */ - Blockly.JavaScript['oh_ephemeris_check'] = function (block) { - const ephemeris = addEphemeris() - - let dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE) - let checkType = block.getFieldValue('checkType') + javascriptGenerator['oh_ephemeris_check'] = function (block) { + const ephemeris = (isGraalJs) ? 'actions.Ephemeris' : addEphemeris() + const dayInfo = javascriptGenerator.valueToCode(block, 'dayInfo', javascriptGenerator.ORDER_NONE) + const checkType = block.getFieldValue('checkType') let code = '' switch (checkType) { @@ -54,7 +54,7 @@ export default function (f7) { code += `${ephemeris}.isBankHoliday(${dayInfo})` break } - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL] + return [code, javascriptGenerator.ORDER_FUNCTION_CALL] } /* @@ -79,11 +79,10 @@ export default function (f7) { * Retrieve the current bonk holiday name * Code part */ - Blockly.JavaScript['oh_ephemeris_getHolidayName'] = function (block) { - const ephemeris = addEphemeris() - let dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE) - let code = `${ephemeris}.getBankHolidayName(${dayInfo})` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_ephemeris_getHolidayName'] = function (block) { + const ephemeris = (isGraalJs) ? 'actions.Ephemeris' : addEphemeris() + const dayInfo = javascriptGenerator.valueToCode(block, 'dayInfo', javascriptGenerator.ORDER_NONE) + return [`${ephemeris}.getBankHolidayName(${dayInfo})`, javascriptGenerator.ORDER_NONE] } /* @@ -107,19 +106,18 @@ export default function (f7) { * Retrieve the number of days from today until the given bank holiday name * Code part */ - Blockly.JavaScript['oh_ephemeris_getDaysUntilHoliday'] = function (block) { - const ephemeris = addEphemeris() - let holidayName = Blockly.JavaScript.valueToCode(block, 'holidayName', Blockly.JavaScript.ORDER_NONE) - let code = `${ephemeris}.getDaysUntil(${holidayName})` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_ephemeris_getDaysUntilHoliday'] = function (block) { + const ephemeris = (isGraalJs) ? 'actions.Ephemeris' : addEphemeris() + const holidayName = javascriptGenerator.valueToCode(block, 'holidayName', javascriptGenerator.ORDER_NONE) + return [`${ephemeris}.getDaysUntil(${holidayName})`, javascriptGenerator.ORDER_NONE] } /* * Add ephemeris support to rule */ function addEphemeris () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'ephemeris', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Ephemeris");']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Ephemeris");']) } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-eventbus.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-eventbus.js index ac4dc0ddfb..1ca454bddf 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-eventbus.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-eventbus.js @@ -1,10 +1,12 @@ /* * Interact with the event bus in Blockly + * supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { Blockly.Blocks['oh_event'] = { init: function () { this.appendValueInput('value') @@ -12,7 +14,7 @@ export default function (f7) { this.appendValueInput('itemName') .appendField('to') .setAlign(Blockly.ALIGN_RIGHT) - .setCheck('String') + .setCheck(['String', 'oh_item']) this.setInputsInline(true) this.setPreviousStatement(true, null) this.setNextStatement(true, null) @@ -22,10 +24,14 @@ export default function (f7) { } } - Blockly.JavaScript['oh_event'] = function (block) { + javascriptGenerator['oh_event'] = function (block) { const eventType = block.getFieldValue('eventType') - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) - const value = Blockly.JavaScript.valueToCode(block, 'value', Blockly.JavaScript.ORDER_ATOMIC) - return 'events.' + eventType + '(' + itemName + ', ' + value + ');\n' + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + const value = javascriptGenerator.valueToCode(block, 'value', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `items.getItem(${itemName}).${eventType}(${value});\n` + } else { + return `events.${eventType}(${itemName}, ${value});\n` + } } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js index e06ad3e799..5a5d771032 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js @@ -1,12 +1,14 @@ /* -* General item and thing functionally for blockly +* General Item functionality for blockly +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldItemModelPicker } from './fields/item-field' import { FieldThingPicker } from './fields/thing-field' -export default function (f7) { +export default function (f7, isGraalJs) { /* Helper block to allow selecting an item */ Blockly.Blocks['oh_item'] = { init: function () { @@ -17,14 +19,13 @@ export default function (f7) { this.setInputsInline(true) this.setTooltip('Pick an item from the Model') this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#item') - this.setOutput(true, null) + this.setOutput(true, 'oh_item') } } - Blockly.JavaScript['oh_item'] = function (block) { + javascriptGenerator['oh_item'] = function (block) { const itemName = block.getFieldValue('itemName') - let code = `'${itemName}'` - return [code, 0] + return [`'${itemName}'`, 0] } /* retrieve members of a group */ @@ -32,7 +33,7 @@ export default function (f7) { init: function () { this.appendValueInput('groupName') .appendField('get members of group') - .setCheck('String') + .setCheck(['String', 'oh_item']) this.setInputsInline(false) this.setOutput(true, 'Array') this.setColour(0) @@ -42,10 +43,14 @@ export default function (f7) { } } - Blockly.JavaScript['oh_groupmembers'] = function (block) { - const groupName = Blockly.JavaScript.valueToCode(block, 'groupName', Blockly.JavaScript.ORDER_ATOMIC) - let code = `Java.from(itemRegistry.getItem(${groupName}).members)` - return [code, 0] + javascriptGenerator['oh_groupmembers'] = function (block) { + const groupName = javascriptGenerator.valueToCode(block, 'groupName', javascriptGenerator.ORDER_ATOMIC) + + if (isGraalJs) { + return [`items.getItem(${groupName}).members`, 0] + } else { + return [`Java.from(itemRegistry.getItem(${groupName}).members)`, 0] + } } /* retrieve items via their tags */ @@ -63,8 +68,8 @@ export default function (f7) { } } - Blockly.JavaScript['oh_taggeditems'] = function (block) { - let tagNames = Blockly.JavaScript.valueToCode(block, 'tagName', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_taggeditems'] = function (block) { + let tagNames = javascriptGenerator.valueToCode(block, 'tagName', javascriptGenerator.ORDER_ATOMIC) tagNames = tagNames.split(',') let tags = '' for (let i = 0; i < tagNames.length; i++) { @@ -73,15 +78,19 @@ export default function (f7) { } tags += tagNames[i] } - let code = `Java.from(itemRegistry.getItemsByTag(${tags}))` - return [code, 0] + + if (isGraalJs) { + return [`items.getItemsByTag(${tags})`, 0] + } else { + return [`Java.from(itemRegistry.getItemsByTag(${tags}))`, 0] + } } Blockly.Blocks['oh_getitem'] = { init: function () { this.appendValueInput('itemName') .appendField('get item') - .setCheck('String') + .setCheck(['String', 'oh_item']) this.setInputsInline(false) this.setOutput(true, 'oh_itemtype') this.setColour(0) @@ -90,10 +99,13 @@ export default function (f7) { } } - Blockly.JavaScript['oh_getitem'] = function (block) { - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) - let code = `itemRegistry.getItem(${itemName})` - return [code, 0] + javascriptGenerator['oh_getitem'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`items.getItem(${itemName})`, 0] + } else { + return [`itemRegistry.getItem(${itemName})`, 0] + } } /* get info from items */ @@ -101,7 +113,7 @@ export default function (f7) { init: function () { this.appendValueInput('itemName') .appendField('get state of item') - .setCheck('String') + .setCheck(['String', 'oh_item']) this.setInputsInline(false) this.setOutput(true, 'String') this.setColour(0) @@ -110,10 +122,13 @@ export default function (f7) { } } - Blockly.JavaScript['oh_getitem_state'] = function (block) { - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) - let code = `itemRegistry.getItem(${itemName}).getState()` - return [code, 0] + javascriptGenerator['oh_getitem_state'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`items.getItem(${itemName}).state`, 0] + } else { + return [`itemRegistry.getItem(${itemName}).getState()`, 0] + } } /* @@ -136,10 +151,10 @@ export default function (f7) { thisBlock.updateType_(newMode) }) this.appendValueInput('item') + .setCheck('oh_itemtype') .appendField('get ') .appendField(dropdown, 'attributeName') .appendField('of item') - .setCheck('oh_itemtype') this.setInputsInline(false) this.setOutput(true, 'String') this.setColour(0) @@ -181,15 +196,19 @@ export default function (f7) { * Provides all attributes from an item * Code part */ - Blockly.JavaScript['oh_getitem_attribute'] = function (block) { - const theItem = Blockly.JavaScript.valueToCode(block, 'item', Blockly.JavaScript.ORDER_ATOMIC) - const attributeName = block.getFieldValue('attributeName') - let code = '' - if (attributeName === 'Tags' || attributeName === 'GroupNames') { - code = `Java.from(${theItem}.get${attributeName}())` + javascriptGenerator['oh_getitem_attribute'] = function (block) { + const theItem = javascriptGenerator.valueToCode(block, 'item', javascriptGenerator.ORDER_ATOMIC) + let attributeName = block.getFieldValue('attributeName') + + if (isGraalJs) { + attributeName = attributeName.charAt(0).toLowerCase() + attributeName.slice(1) + return [`${theItem}.${attributeName}`, 0] } else { - code = `${theItem}.get${attributeName}()` + if (attributeName === 'Tags' || attributeName === 'GroupNames') { + return [`Java.from(${theItem}.get${attributeName}())`, 0] + } else { + return [`${theItem}.get${attributeName}()`, 0] + } } - return [code, 0] } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js index 15733020b8..17cbac2e30 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js @@ -1,10 +1,12 @@ /* * Adds new blocks to the list section +* supports jsscripting */ import Blockly from 'blockly' -export default function (f7) { +import { javascriptGenerator } from 'blockly/javascript' +export default function (f7, isGraalJs) { /* - * allows the concatenate a list into a new list + * allows to concatenate a list into a new list * Block */ Blockly.Blocks['oh_list_concatenate'] = { @@ -24,10 +26,10 @@ export default function (f7) { } } - Blockly.JavaScript['oh_list_concatenate'] = function (block) { - const list1 = Blockly.JavaScript.valueToCode(block, 'list1', Blockly.JavaScript.ORDER_ATOMIC) - const list2 = Blockly.JavaScript.valueToCode(block, 'list2', Blockly.JavaScript.ORDER_ATOMIC) - const code = list1 + '.concat(' + list2 + ');\n' + javascriptGenerator['oh_list_concatenate'] = function (block) { + const list1 = javascriptGenerator.valueToCode(block, 'list1', javascriptGenerator.ORDER_ATOMIC) + const list2 = javascriptGenerator.valueToCode(block, 'list2', javascriptGenerator.ORDER_ATOMIC) + const code = list1 + '.concat(' + list2 + ')' return [code, 0] } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-logging.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-logging.js index bd28ef5d06..18aca79e92 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-logging.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-logging.js @@ -1,10 +1,12 @@ /* * Logging functionality for blockly +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { Blockly.Blocks['oh_print'] = { init: function () { this.appendValueInput('message') @@ -17,32 +19,38 @@ export default function (f7) { } } - Blockly.JavaScript['oh_print'] = function (block) { - const message = Blockly.JavaScript.valueToCode(block, 'message', Blockly.JavaScript.ORDER_ATOMIC) - let code = `print(${message});\n` - return code + javascriptGenerator['oh_print'] = function (block) { + const message = javascriptGenerator.valueToCode(block, 'message', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `console.log(${message});\n` + } else { + return `print(${message});\n` + } } Blockly.Blocks['oh_log'] = { init: function () { this.appendValueInput('message') .appendField('log') - .appendField(new Blockly.FieldDropdown([['error', 'error'], ['warn', 'warn'], ['info', 'info'], ['debug', 'debug'], ['trace', 'trace']]), 'severity') + .appendField(new Blockly.FieldDropdown([['info', 'info'], ['error', 'error'], ['warn', 'warn'], ['debug', 'debug'], ['trace', 'trace']]), 'severity') this.setPreviousStatement(true, null) this.setNextStatement(true, null) this.setColour(0) - this.setTooltip('Write a message in the openHAB log') + this.setTooltip('Write a message in the openHAB log with the severity level') this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-logging.html#log-statement') } } - Blockly.JavaScript['oh_log'] = function (block) { - const logger = Blockly.JavaScript.provideFunction_( - 'logger', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.slf4j.LoggerFactory\').getLogger(\'org.openhab.rule.\' + ctx.ruleUID);']) - const message = Blockly.JavaScript.valueToCode(block, 'message', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_log'] = function (block) { + const message = javascriptGenerator.valueToCode(block, 'message', javascriptGenerator.ORDER_ATOMIC) const severity = block.getFieldValue('severity') - const code = `${logger}.${severity}(${message});\n` - return code + if (isGraalJs) { + return `console.${severity}(${message});\n` + } else { + const logger = javascriptGenerator.provideFunction_( + 'logger', + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.slf4j.LoggerFactory\').getLogger(\'org.openhab.rule.\' + ctx.ruleUID);']) + return `${logger}.${severity}(${message});\n` + } } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-notifications.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-notifications.js index b67fc17a5c..eca37f1097 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-notifications.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-notifications.js @@ -1,10 +1,13 @@ /* * These blocks allow to send notifications via openhab +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function defineOHBlocks_Notifications (f7) { +// TODO: Add options to set icon and level (argument order should be the same as for broadcast notification etc.) +export default function defineOHBlocks_Notifications (f7, isGraalJs) { Blockly.Blocks['oh_sendNotification'] = { init: function () { this.appendValueInput('message') @@ -20,12 +23,15 @@ export default function defineOHBlocks_Notifications (f7) { } } - Blockly.JavaScript['oh_sendNotification'] = function (block) { - const notifications = addNotificationAction() - let email = Blockly.JavaScript.valueToCode(block, 'email', Blockly.JavaScript.ORDER_ATOMIC) - let message = Blockly.JavaScript.valueToCode(block, 'message', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${notifications}.sendNotification(${email},${message});\n` - return code + javascriptGenerator['oh_sendNotification'] = function (block) { + let email = javascriptGenerator.valueToCode(block, 'email', javascriptGenerator.ORDER_ATOMIC) + let message = javascriptGenerator.valueToCode(block, 'message', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `actions.NotificationAction.sendNotification(${email}, ${message});\n` + } else { + const notifications = addNotificationAction() + return `${notifications}.sendNotification(${email}, ${message});\n` + } } Blockly.Blocks['oh_sendBroadcastNotification'] = { @@ -47,13 +53,16 @@ export default function defineOHBlocks_Notifications (f7) { } } - Blockly.JavaScript['oh_sendBroadcastNotification'] = function (block) { - const notifications = addNotificationAction() - let message = Blockly.JavaScript.valueToCode(block, 'message', Blockly.JavaScript.ORDER_ATOMIC) - let icon = Blockly.JavaScript.valueToCode(block, 'icon', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_sendBroadcastNotification'] = function (block) { + let message = javascriptGenerator.valueToCode(block, 'message', javascriptGenerator.ORDER_ATOMIC) + let icon = javascriptGenerator.valueToCode(block, 'icon', javascriptGenerator.ORDER_ATOMIC) let severity = block.getFieldValue('severity') - let code = `${notifications}.sendBroadcastNotification(${message},${icon},'${severity}');\n` - return code + if (isGraalJs) { + return `actions.NotificationAction.sendBroadcastNotification(${message}, ${icon}, '${severity}');\n` + } else { + const notifications = addNotificationAction() + return `${notifications}.sendBroadcastNotification(${message}, ${icon}, '${severity}');\n` + } } Blockly.Blocks['oh_sendLogNotification'] = { @@ -75,18 +84,21 @@ export default function defineOHBlocks_Notifications (f7) { } } - Blockly.JavaScript['oh_sendLogNotification'] = function (block) { - const notifications = addNotificationAction() - let message = Blockly.JavaScript.valueToCode(block, 'message', Blockly.JavaScript.ORDER_ATOMIC) - let icon = Blockly.JavaScript.valueToCode(block, 'icon', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_sendLogNotification'] = function (block) { + let message = javascriptGenerator.valueToCode(block, 'message', javascriptGenerator.ORDER_ATOMIC) + let icon = javascriptGenerator.valueToCode(block, 'icon', javascriptGenerator.ORDER_ATOMIC) let severity = block.getFieldValue('severity') - let code = `${notifications}.sendLogNotification(${message},${icon},'${severity}');\n` - return code + if (isGraalJs) { + return `actions.NotificationAction.sendLogNotification(${message}, ${icon}, '${severity}');\n` + } else { + const notifications = addNotificationAction() + return `${notifications}.sendLogNotification(${message}, ${icon}, '${severity}');\n` + } } } function addNotificationAction () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'notifications', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.io.openhabcloud.NotificationAction\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.io.openhabcloud.NotificationAction\');']) } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js index d4fb784461..268ea3149f 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js @@ -1,10 +1,12 @@ /* * These blocks support the persistence module which stores the data in the database and allows to retrieve historical and statistical data +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { addDateSupport } from './utils' -export default function defineOHBlocks_Persistence (f7) { +export default function defineOHBlocks_Persistence (f7, isGraalJs) { /* * Provides a number of different (non-)statistical metrics for an item according to the given date * Blockly part @@ -24,7 +26,7 @@ export default function defineOHBlocks_Persistence (f7) { this.appendValueInput('itemName') .appendField('of the state of item named ') .setAlign(Blockly.ALIGN_RIGHT) - .setCheck('String', 'oh_item') + .setCheck(['String', 'oh_item']) this.updateShape() this.setInputsInline(false) this.setOutput(true, null) @@ -84,41 +86,40 @@ export default function defineOHBlocks_Persistence (f7) { * Provides a number of different (non-)statistical metrics for an item according to the given date * Code part */ - Blockly.JavaScript['oh_get_persistvalue'] = function (block) { - const { dtf, zdt, getZonedDatetime } = addDateSupport() - const persistence = addPersistence() - - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_get_persistvalue'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) const methodName = block.getFieldValue('methodName') + const persistence = (isGraalJs) ? null : addPersistence() + let code = '' let dayInfo = '' switch (methodName) { case 'maximumSince': case 'minimumSince': - dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE) - code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo}).getState()` + dayInfo = javascriptGenerator.valueToCode(block, 'dayInfo', javascriptGenerator.ORDER_NONE) + code = (isGraalJs) ? `items.getItem(${itemName}).history.${methodName}(${dayInfo})` : `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo}).getState()` break case 'previousState': case 'previousStateTime': - let skipPrevious = Blockly.JavaScript.valueToCode(block, 'skipPrevious', Blockly.JavaScript.ORDER_NONE) + let skipPrevious = javascriptGenerator.valueToCode(block, 'skipPrevious', javascriptGenerator.ORDER_NONE) skipPrevious = ((skipPrevious === 'undefined') ? false : skipPrevious) if (methodName === 'previousState') { - code = `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getState(): 'undefined')` + code = (isGraalJs) ? `items.getItem(${itemName}).history.${methodName}(${skipPrevious})` : `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getState() : 'undefined')` } else if (methodName === 'previousStateTime') { - code = `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getTimestamp() : 'undefined')` + code = (isGraalJs) ? `items.getItem(${itemName}).history.${methodName}(${skipPrevious})` : `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getTimestamp() : 'undefined')` } break default: - dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE) - code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})` + dayInfo = javascriptGenerator.valueToCode(block, 'dayInfo', javascriptGenerator.ORDER_NONE) + code = (isGraalJs) ? `items.getItem(${itemName}).history.${methodName}(${dayInfo})` : `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})` break } - return [code, Blockly.JavaScript.ORDER_NONE] + return [code, javascriptGenerator.ORDER_NONE] } /* @@ -156,15 +157,18 @@ export default function defineOHBlocks_Persistence (f7) { * Checks if an item has changed or has been updated since some given date * Code part */ - Blockly.JavaScript['oh_persist_changed'] = function (block) { - const { dtf, zdt, getZonedDatetime } = addDateSupport() - const persistence = addPersistence() - - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_persist_changed'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) const methodName = block.getFieldValue('methodName') - const dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE) - let code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})` - return [code, Blockly.JavaScript.ORDER_NONE] + const dayInfo = javascriptGenerator.valueToCode(block, 'dayInfo', javascriptGenerator.ORDER_NONE) + + if (isGraalJs) { + return [`items.getItem(${itemName}).history.${methodName}(${dayInfo})`, javascriptGenerator.ORDER_NONE] + } else { + const { dtf, zdt, getZonedDatetime } = addDateSupport() + const persistence = addPersistence() + return [`${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})`, javascriptGenerator.ORDER_NONE] + } } /* @@ -188,17 +192,22 @@ export default function defineOHBlocks_Persistence (f7) { * Returns the state before the current state of that item * Code part */ - Blockly.JavaScript['oh_get_persistence_lastupdate'] = function (block) { - const { dtf, zdt, getZonedDatetime } = addDateSupport() - const persistence = addPersistence() - const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${persistence}.lastUpdate(itemRegistry.getItem(${itemName}))` - return [code, 0] + javascriptGenerator['oh_get_persistence_lastupdate'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + + if (isGraalJs) { + return [`items.getItem(${itemName}).history.lastUpdate()`, 0] + } else { + const { dtf, zdt, getZonedDatetime } = addDateSupport() + const persistence = addPersistence() + let code = `${persistence}.lastUpdate(itemRegistry.getItem(${itemName}))` + return [code, 0] + } } function addPersistence () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'persistence', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.persistence.extensions.PersistenceExtensions\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.persistence.extensions.PersistenceExtensions\');']) } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js index 1792a08e7d..1bb84e0ff5 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js @@ -1,13 +1,15 @@ /* * These blocks allow to run scripts from the current rule. There are two types of scripts which are supported by different blocks -* - Script Files that are stored on openHAB's server in the scripts folder +* - Script Files that are stored on the openHAB server in the "$OPENHAB_CONF/scripts" folder * - Scripts that have been provided via the openHAB UI * Additionally there is a block that allows transformations based on the Map-File functionality, regular-expressions and applying JSON-paths +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { addOSGiService } from './utils' -export default function defineOHBlocks_Scripts (f7, scripts) { +export default function defineOHBlocks_Scripts (f7, isGraalJs, scripts) { /* * Calls a script that is provided in openHABs scripts folder * Blockly part @@ -30,13 +32,16 @@ export default function defineOHBlocks_Scripts (f7, scripts) { * Calls a script that is provided in openHABs scripts folder * Code part */ - Blockly.JavaScript['oh_callscriptfile'] = function (block) { - const scriptExecution = Blockly.JavaScript.provideFunction_( - 'scriptExecution', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.ScriptExecution\');']) - let scriptfile = Blockly.JavaScript.valueToCode(block, 'scriptfile', Blockly.JavaScript.ORDER_ATOMIC) - let code = `${scriptExecution}.callScript(${scriptfile});\n` - return code + javascriptGenerator['oh_callscriptfile'] = function (block) { + let scriptfile = javascriptGenerator.valueToCode(block, 'scriptfile', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `actions.ScriptExecution.callScript(${scriptfile});\n` + } else { + const scriptExecution = javascriptGenerator.provideFunction_( + 'scriptExecution', + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.ScriptExecution\');']) + return `${scriptExecution}.callScript(${scriptfile});\n` + } } /* @@ -66,27 +71,29 @@ export default function defineOHBlocks_Scripts (f7, scripts) { * Parameters can be provided with the special parameter block oh_scriptparam * Code part */ - Blockly.JavaScript['oh_runrule'] = function (block) { - const ruleManager = addOSGiService('ruleManager', 'org.openhab.core.automation.RuleManager') - const ruleUID = Blockly.JavaScript.valueToCode(block, 'ruleUID', Blockly.JavaScript.ORDER_ATOMIC) - const scriptParameters = Blockly.JavaScript.valueToCode(block, 'parameters', Blockly.JavaScript.ORDER_ATOMIC) - - // create a function for the generated code that maps json key-values into a map structure - const convertDictionaryToHashMap = Blockly.JavaScript.provideFunction_( - 'convertDictionaryToHashMap', - [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' (dict) {', - ' if (!dict || dict.length === 0) return null;', - ' var map = new java.util.HashMap();', - ' Object.keys(dict).forEach(function (key) {', - ' map.put(key, dict[key]);', - ' });', - ' return map;', - '}' - ]) - - let code = `${ruleManager}.runNow(${ruleUID}, true, ${convertDictionaryToHashMap}(${scriptParameters}));\n` - return code + javascriptGenerator['oh_runrule'] = function (block) { + const ruleUID = javascriptGenerator.valueToCode(block, 'ruleUID', javascriptGenerator.ORDER_ATOMIC) + const scriptParameters = javascriptGenerator.valueToCode(block, 'parameters', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `rules.runRule(${ruleUID}, ${scriptParameters});\n` + } else { + const ruleManager = addOSGiService('ruleManager', 'org.openhab.core.automation.RuleManager') + // create a function for the generated code that maps json key-values into a map structure + const convertDictionaryToHashMap = javascriptGenerator.provideFunction_( + 'convertDictionaryToHashMap', + [ + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' (dict) {', + ' if (!dict || dict.length === 0) return null;', + ' var map = new java.util.HashMap();', + ' Object.keys(dict).forEach(function (key) {', + ' map.put(key, dict[key]);', + ' });', + ' return map;', + '}' + ]) + + return `${ruleManager}.runNow(${ruleUID}, true, ${convertDictionaryToHashMap}(${scriptParameters}));\n` + } } /* @@ -136,16 +143,19 @@ export default function defineOHBlocks_Scripts (f7, scripts) { * Allow transformations via different methods * Code part */ - Blockly.JavaScript['oh_transformation'] = function (block) { - const transformation = Blockly.JavaScript.provideFunction_( - 'transformation', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.transform.actions.Transformation\');']) + javascriptGenerator['oh_transformation'] = function (block) { const transformationType = block.getFieldValue('type') - const transformationFunction = Blockly.JavaScript.valueToCode(block, 'function', Blockly.JavaScript.ORDER_ATOMIC) - const transformationValue = Blockly.JavaScript.valueToCode(block, 'value', Blockly.JavaScript.ORDER_ATOMIC) + const transformationFunction = javascriptGenerator.valueToCode(block, 'function', javascriptGenerator.ORDER_ATOMIC) + const transformationValue = javascriptGenerator.valueToCode(block, 'value', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`actions.Transformation.transform('${transformationType}', ${transformationFunction}, ${transformationValue})`, 0] + } else { + const transformation = javascriptGenerator.provideFunction_( + 'transformation', + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.transform.actions.Transformation\');']) - let code = `${transformation}.transform('${transformationType}', ${transformationFunction}, ${transformationValue})` - return [code, 0] + return [`${transformation}.transform('${transformationType}', ${transformationFunction}, ${transformationValue})`, 0] + } } Blockly.Blocks['oh_context_info'] = { @@ -185,10 +195,10 @@ export default function defineOHBlocks_Scripts (f7, scripts) { } } - Blockly.JavaScript['oh_context_info'] = function (block) { + javascriptGenerator['oh_context_info'] = function (block) { const contextInfo = block.getFieldValue('contextInfo') - if (contextInfo === 'ruleUID') return ['ctx.ruleUID', Blockly.JavaScript.ORDER_ATOMIC] - return [`event.${contextInfo}`, Blockly.JavaScript.ORDER_ATOMIC] + if (contextInfo === 'ruleUID') return ['ctx.ruleUID', javascriptGenerator.ORDER_ATOMIC] + return [`event.${contextInfo}`, javascriptGenerator.ORDER_ATOMIC] } /* @@ -212,8 +222,8 @@ export default function defineOHBlocks_Scripts (f7, scripts) { * Allows retrieving parameters provided by a rule * Code part */ - Blockly.JavaScript['oh_context_attribute'] = function (block) { - const key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_context_attribute'] = function (block) { + const key = javascriptGenerator.valueToCode(block, 'key', javascriptGenerator.ORDER_ATOMIC) let code = `ctx[${key}]` return [code, 0] } @@ -226,8 +236,14 @@ export default function defineOHBlocks_Scripts (f7, scripts) { init: function () { this.appendDummyInput() .appendField('inline script (advanced)') + let code = '' + if (isGraalJs) { + code = 'for (var i = 0; i < 10; i++) {\n console.log(i.toString());\n}' + } else { + code = 'for (var i = 0; i < 10; i++) {\n print(i.toString());\n}' + } this.appendDummyInput() - .appendField(new Blockly.FieldMultilineInput('for (var i = 0; i < 10; i++) {\n print(i.toString());\n}'), 'inlineScript') + .appendField(new Blockly.FieldMultilineInput(code), 'inlineScript') this.setInputsInline(false) this.setPreviousStatement(true, null) this.setNextStatement(true, null) @@ -241,7 +257,7 @@ export default function defineOHBlocks_Scripts (f7, scripts) { * Allows inlining arbitrary code * Code part */ - Blockly.JavaScript['oh_script_inline'] = function (block) { + javascriptGenerator['oh_script_inline'] = function (block) { const code = block.getFieldValue('inlineScript') + '\n' return code } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js index 7d57158cb9..9f3dd40077 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js @@ -1,10 +1,12 @@ /* * Adds new blocks to the text section +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function (f7) { +export default function (f7, isGraalJs) { /* * allows adding a CR/LF in string concatenation * Block @@ -21,9 +23,8 @@ export default function (f7) { } } - Blockly.JavaScript['oh_text_crlf'] = function (block) { - let code = '\'\\r\\n\'' - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_text_crlf'] = function (block) { + return ['\'\\r\\n\'', javascriptGenerator.ORDER_NONE] } /* @@ -51,10 +52,10 @@ export default function (f7) { } } - Blockly.JavaScript['oh_text_replace'] = function (block) { - const pattern = Blockly.JavaScript.valueToCode(block, 'pattern', Blockly.JavaScript.ORDER_ATOMIC) - const replacement = Blockly.JavaScript.valueToCode(block, 'replacement', Blockly.JavaScript.ORDER_ATOMIC) - const originText = Blockly.JavaScript.valueToCode(block, 'origin', Blockly.JavaScript.ORDER_ATOMIC) + javascriptGenerator['oh_text_replace'] = function (block) { + const pattern = javascriptGenerator.valueToCode(block, 'pattern', javascriptGenerator.ORDER_ATOMIC) + const replacement = javascriptGenerator.valueToCode(block, 'replacement', javascriptGenerator.ORDER_ATOMIC) + const originText = javascriptGenerator.valueToCode(block, 'origin', javascriptGenerator.ORDER_ATOMIC) const code = originText + '.replaceAll(' + pattern + ',' + replacement + ')' return [code, 0] } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-things.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-things.js index 4c4134cc5d..0b5bb14dbd 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-things.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-things.js @@ -1,12 +1,14 @@ /* -* General item and thing functionally for blockly +* General Thing functionality for blockly +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { FieldItemModelPicker } from './fields/item-field' import { FieldThingPicker } from './fields/thing-field' -export default function defineOHBlocks (f7) { +export default function defineOHBlocks (f7, isGraalJs) { Blockly.Blocks['oh_thing'] = { init: function () { this.appendDummyInput() @@ -20,7 +22,7 @@ export default function defineOHBlocks (f7) { } } - Blockly.JavaScript['oh_thing'] = function (block) { + javascriptGenerator['oh_thing'] = function (block) { const thingUid = block.getFieldValue('thingUid') let code = `'${thingUid}'` return [code, 0] @@ -30,7 +32,7 @@ export default function defineOHBlocks (f7) { init: function () { this.appendValueInput('thingUid') .appendField('get thing status') - .setCheck('String') + .setCheck(['String', 'oh_thing']) this.setInputsInline(false) this.setOutput(true, 'String') this.setColour(0) @@ -39,12 +41,15 @@ export default function defineOHBlocks (f7) { } } - Blockly.JavaScript['oh_getthing_state'] = function (block) { - const things = Blockly.JavaScript.provideFunction_( - 'things', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Things")']) - const thingUid = Blockly.JavaScript.valueToCode(block, 'thingUid', Blockly.JavaScript.ORDER_ATOMIC) - let code = `things.getThingStatusInfo(${thingUid}).getStatus()` - return [code, 0] + javascriptGenerator['oh_getthing_state'] = function (block) { + const thingUid = javascriptGenerator.valueToCode(block, 'thingUid', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`things.getThing(${thingUid}).status`, 0] + } else { + const things = javascriptGenerator.provideFunction_( + 'things', + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("org.openhab.core.model.script.actions.Things")']) + return [`things.getThingStatusInfo(${thingUid}).getStatus()`, 0] + } } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-timers.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-timers.js index f9b6fd69e3..f517b96699 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-timers.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-timers.js @@ -1,10 +1,12 @@ /* * Blockly blocks to create timers & delays + * supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function defineOHBlocks_Timers (f7) { +export default function defineOHBlocks_Timers (f7, isGraalJs) { /* * Sleeps for the number of milliseconds * @@ -29,10 +31,10 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_sleep'] = function (block) { - const thread = Blockly.JavaScript.provideFunction_( + javascriptGenerator['oh_sleep'] = function (block) { + const thread = javascriptGenerator.provideFunction_( 'thread', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.lang.Thread\')']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.lang.Thread\')']) let milliseconds = block.getFieldValue('milliseconds') let code = `${thread}.sleep(${milliseconds});\n` @@ -69,22 +71,31 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer'] = function (block) { - const scriptExecution = addScriptExecution() - const zdt = addZonedDateTime() - addGlobalTimer() + javascriptGenerator['oh_timer'] = function (block) { + const delayUnits = block.getFieldValue('delayUnits') + const delay = javascriptGenerator.valueToCode(block, 'delay', javascriptGenerator.ORDER_ATOMIC) + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + const timerCode = javascriptGenerator.statementToCode(block, 'timerCode') - let delayunits = block.getFieldValue('delayUnits') - let delay = Blockly.JavaScript.valueToCode(block, 'delay', Blockly.JavaScript.ORDER_ATOMIC) - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - let timerCode = Blockly.JavaScript.statementToCode(block, 'timerCode') - - let code = `if (typeof this.timers[${timerName}] === 'undefined' || this.timers[${timerName}].hasTerminated()) {\n` - code += ` this.timers[${timerName}] = ${scriptExecution}.createTimer(${zdt}.now().${delayunits}(${delay}), function () {\n` - code += timerCode.replace(/^/gm, ' ') - code += ' })\n' - code += '}\n' - return code + if (isGraalJs) { + let code = `if (cache.private.exists(${timerName}) === false || cache.private.get(${timerName}).hasTerminated()) {\n` + code += ` cache.private.put(${timerName}, actions.ScriptExecution.createTimer(${timerName}, time.ZonedDateTime.now().${delayUnits}(${delay}), function () {\n` + code += timerCode.replace(/^/gm, ' ') + code += ` cache.private.remove(${timerName});\n` + code += ' }));\n' + code += '};\n' + return code + } else { + addGlobalTimer() + const scriptExecution = addScriptExecution() + const zdt = addZonedDateTime() + let code = `if (typeof this.timers[${timerName}] === 'undefined' || this.timers[${timerName}].hasTerminated()) {\n` + code += ` this.timers[${timerName}] = ${scriptExecution}.createTimer(${zdt}.now().${delayUnits}(${delay}), function () {\n` + code += timerCode.replace(/^/gm, ' ') + code += ' })\n' + code += '}\n' + return code + } } /* @@ -119,38 +130,61 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_ext'] = function (block) { - const scriptExecution = addScriptExecution() - const zdt = addZonedDateTime() - addGlobalTimer() + javascriptGenerator['oh_timer_ext'] = function (block) { + const delayUnits = block.getFieldValue('delayUnits') + const delay = javascriptGenerator.valueToCode(block, 'delay', javascriptGenerator.ORDER_ATOMIC) + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + const timerCode = javascriptGenerator.statementToCode(block, 'timerCode') + const retrigger = block.getFieldValue('retrigger') + + if (isGraalJs) { + let code = `if (cache.private.exists(${timerName}) === false || cache.private.get(${timerName}).hasTerminated()) {\n` + code += ` cache.private.put(${timerName}, actions.ScriptExecution.createTimer(${timerName}, time.ZonedDateTime.now().${delayUnits}(${delay}), function () {\n` + code += timerCode.replace(/^/gm, ' ') + code += ` cache.private.remove(${timerName});\n` + code += ' }));\n' + code += '} else {\n' + switch (retrigger) { + case 'reschedule': + code += ` cache.private.get(${timerName}).reschedule(time.ZonedDateTime.now().${delayUnits}(${delay}));\n` + break - let delay = Blockly.JavaScript.valueToCode(block, 'delay', Blockly.JavaScript.ORDER_ATOMIC) - let delayUnits = block.getFieldValue('delayUnits') - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - let retrigger = block.getFieldValue('retrigger') - let timerCode = Blockly.JavaScript.statementToCode(block, 'timerCode') + case 'cancel': + code += ` cache.private.remove(${timerName}).cancel();\n` + break - let code = `if (typeof this.timers[${timerName}] === 'undefined' || this.timers[${timerName}].hasTerminated()) {\n` - code += ` this.timers[${timerName}] = ${scriptExecution}.createTimer(${zdt}.now().${delayUnits}(${delay}), function () {\n` - code += timerCode.replace(/^/gm, ' ') - code += ' })\n' - code += '} else {\n' - switch (retrigger) { - case 'reschedule': - code += ` this.timers[${timerName}].reschedule(${zdt}.now().${delayUnits}(${delay}));\n` - break + case 'nothing': + code += ' // do nothing\n' + break + } + code += '};\n' + return code + } else { + addGlobalTimer() + const scriptExecution = addScriptExecution() + const zdt = addZonedDateTime() + let code = `if (typeof this.timers[${timerName}] === 'undefined' || this.timers[${timerName}].hasTerminated()) {\n` + code += ` this.timers[${timerName}] = ${scriptExecution}.createTimer(${zdt}.now().${delayUnits}(${delay}), function () {\n` + code += timerCode.replace(/^/gm, ' ') + code += ' })\n' + code += '} else {\n' + switch (retrigger) { + case 'reschedule': + code += ` this.timers[${timerName}].reschedule(${zdt}.now().${delayUnits}(${delay}));\n` + break - case 'cancel': - code += ` this.timers[${timerName}].cancel();\n` - code += ` this.timers[${timerName}] = undefined;\n` - break + case 'cancel': + code += ` this.timers[${timerName}].cancel();\n` + code += ` this.timers[${timerName}] = undefined;\n` + break - case 'nothing': - code += ' // do nothing\n' - break + case 'nothing': + code += ' // do nothing\n' + break + } + code += '}\n' + return code } - code += '}\n' - return code } /* @@ -178,12 +212,16 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_isActive'] = function (block) { - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - addGlobalTimer() + javascriptGenerator['oh_timer_isActive'] = function (block) { + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`cache.private.exists(${timerName}) && cache.private.get(${timerName}).isActive()`, javascriptGenerator.ORDER_NONE] + } else { + addGlobalTimer() - let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].isActive()` - return [code, Blockly.JavaScript.ORDER_NONE] + let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].isActive()` + return [code, javascriptGenerator.ORDER_NONE] + } } /* @@ -211,11 +249,17 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_isRunning'] = function (block) { - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - addGlobalTimer() - let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].isRunning()` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_timer_isRunning'] = function (block) { + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + // Keep the isRunning block although it doesn't make sense because in GraalJS access to the context is synchronized and therefore it is not possible to run some code the same time a timer is running + return [`cache.private.exists(${timerName}) && cache.private.get(${timerName}).isRunning()`, javascriptGenerator.ORDER_NONE] + } else { + addGlobalTimer() + + let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].isRunning()` + return [code, javascriptGenerator.ORDER_NONE] + } } /* @@ -243,11 +287,16 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_hasTerminated'] = function (block) { - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - addGlobalTimer() - let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].hasTerminated()` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_timer_hasTerminated'] = function (block) { + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return [`cache.private.exists(${timerName}) && cache.private.get(${timerName}).hasTerminated()`, javascriptGenerator.ORDER_NONE] + } else { + addGlobalTimer() + + let code = `typeof this.timers[${timerName}] !== 'undefined' && this.timers[${timerName}].hasTerminated()` + return [code, javascriptGenerator.ORDER_NONE] + } } /* @@ -273,15 +322,18 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_cancel'] = function (block) { - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - addGlobalTimer() - let code = `if (typeof this.timers[${timerName}] !== 'undefined') {\n` - code += ` this.timers[${timerName}].cancel();\n` - code += ` this.timers[${timerName}] = undefined;\n` - code += '}\n' - - return code + javascriptGenerator['oh_timer_cancel'] = function (block) { + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `if (cache.private.exists(${timerName})) { cache.private.remove(${timerName}).cancel(); };\n` + } else { + addGlobalTimer() + let code = `if (typeof this.timers[${timerName}] !== 'undefined') {\n` + code += ` this.timers[${timerName}].cancel();\n` + code += ` this.timers[${timerName}] = undefined;\n` + code += '}\n' + return code + } } /* @@ -313,32 +365,35 @@ export default function defineOHBlocks_Timers (f7) { * * Code generation */ - Blockly.JavaScript['oh_timer_reschedule'] = function (block) { - const zdt = addZonedDateTime() - - let delayUnits = block.getFieldValue('delayUnits') - let delay = Blockly.JavaScript.valueToCode(block, 'delay', Blockly.JavaScript.ORDER_ATOMIC) - let timerName = Blockly.JavaScript.valueToCode(block, 'timerName', Blockly.JavaScript.ORDER_ATOMIC) - addGlobalTimer() + javascriptGenerator['oh_timer_reschedule'] = function (block) { + const delayUnits = block.getFieldValue('delayUnits') + const delay = javascriptGenerator.valueToCode(block, 'delay', javascriptGenerator.ORDER_ATOMIC) + const timerName = javascriptGenerator.valueToCode(block, 'timerName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + return `if (cache.private.exists(${timerName})) { cache.private.get(${timerName}).reschedule(time.ZonedDateTime.now().${delayUnits}(${delay})); };\n` + } else { + const zdt = addZonedDateTime() + addGlobalTimer() - let code = `if (typeof this.timers[${timerName}] !== 'undefined') { this.timers[${timerName}].reschedule(${zdt}.now().${delayUnits}(${delay})); }\n` - return code + let code = `if (typeof this.timers[${timerName}] !== 'undefined') { this.timers[${timerName}].reschedule(${zdt}.now().${delayUnits}(${delay})); }\n` + return code + } } function addScriptExecution () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'scriptExecution', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.ScriptExecution\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'org.openhab.core.model.script.actions.ScriptExecution\');']) } function addZonedDateTime () { - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( 'zdt', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.time.ZonedDateTime\');']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type(\'java.time.ZonedDateTime\');']) } function addGlobalTimer () { let globaltimervars = 'if (typeof this.timers === \'undefined\') {\n this.timers = [];\n}' - Blockly.JavaScript.provideFunction_('globaltimervars', [globaltimervars]) + javascriptGenerator.provideFunction_('globaltimervars', [globaltimervars]) } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-uom.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-uom.js new file mode 100644 index 0000000000..b557e6f388 --- /dev/null +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-uom.js @@ -0,0 +1,112 @@ +/* +* Adds new blocks to the colour section +* supports jsscripting +*/ + +import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' + +export default function (f7, isGraalJs) { + Blockly.Blocks['oh_quantity'] = { + init: function () { + this.appendValueInput('quantity') + .setCheck('String') + this.setColour(58) + this.setInputsInline(true) + this.setTooltip('Block that wraps Measurements in a Quantity block.\nA Quantity is a Number plus a Unit (of Measurement). \nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ') + this.setHelpUrl('https://www.openhab.org/docs/concepts/units-of-measurement.html') + this.setOutput(true, ['oh_quantity', 'String']) + } + } + + javascriptGenerator['oh_quantity'] = function (block) { + const quantity = javascriptGenerator.valueToCode(block, 'quantity', javascriptGenerator.ORDER_NONE) + return [`Quantity(${quantity})`, 0] + } + + Blockly.Blocks['oh_quantity_arithmetic'] = { + init: function () { + this.appendValueInput('first') + .setCheck('oh_quantity') + this.appendValueInput('second') + .setCheck(['oh_quantity', 'Number']) + .appendField(new Blockly.FieldDropdown([ + ['+', 'add'], ['-', 'subtract'], + ['*', 'multiply'], ['/', 'divide'] + ]), 'operand') + + this.setInputsInline(true) + this.setOutput(true, 'oh_quantity') + this.setColour('%{BKY_MATH_HUE}') + this.setTooltip('Allows computation with Quantity blocks.\nA Quantity is a Number plus a Unit (of Measurement). \nMake sure you use the right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ') + this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/') + } + } + + javascriptGenerator['oh_quantity_arithmetic'] = function (block) { + if (isGraalJs) { + const first = javascriptGenerator.valueToCode(block, 'first', javascriptGenerator.ORDER_NONE) + const second = javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_NONE) + const operand = block.getFieldValue('operand') + return [`${first}.${operand}(${second})`, javascriptGenerator.ORDER_NONE] + } else { + console.warn('arithmetic function unit of measurement only supported with jsscripting') + } + } + + Blockly.Blocks['oh_quantity_compare'] = { + init: function () { + this.appendValueInput('first') + .setCheck('oh_quantity') + this.appendValueInput('second') + .setCheck('oh_quantity') + .appendField(new Blockly.FieldDropdown([ + ['=', 'equal'], + // ['\u2260', 'NEQ'], // maybe later by adding a not + ['\u200F<', 'smallerThan'], + ['\u200F\u2264', 'smallerThanOrEqual'], + ['\u200F>', 'largerThan'], + ['\u200F\u2265', 'largerThanOrEqual'] + ]), 'operand') + + this.setInputsInline(true) + this.setOutput(true, 'Boolean') + this.setColour('%{BKY_LOGIC_HUE}') + this.setTooltip('Compares two Quantities with each other.\nMake sure you use the target right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ') + this.setHelpUrl('https://www.openhab.org/docs/concepts/units-of-measurement.html') + } + } + + javascriptGenerator['oh_quantity_compare'] = function (block) { + const itemName = javascriptGenerator.valueToCode(block, 'itemName', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + const first = javascriptGenerator.valueToCode(block, 'first', javascriptGenerator.ORDER_NONE) + const second = javascriptGenerator.valueToCode(block, 'second', javascriptGenerator.ORDER_NONE) + const operand = block.getFieldValue('operand') + return [`${first}.${operand}(${second})`, javascriptGenerator.ORDER_NONE] + } else { + console.warn('compare function unit of measurement only supported with jsscripting') + } + } + + Blockly.Blocks['oh_quantity_to_unit'] = { + init: function () { + this.appendValueInput('quantity') + .setCheck('oh_quantity') + this.appendValueInput('unit') + .appendField('to unit') + .setCheck('String') + this.setColour(58) + this.setInputsInline(true) + this.setTooltip('Converts a Quantity into another Unit.\nMake sure you use the target right units like 5.75 m, 1 N*m, 1 m/s, 1 m^2/s^2, 1 m^2/s^-2 ... ') + this.setHelpUrl('https://www.openhab.org/docs/concepts/units-of-measurement.html') + this.setOutput(true, 'oh_quantity') + } + } + + javascriptGenerator['oh_quantity_to_unit'] = function (block) { + const quantity = javascriptGenerator.valueToCode(block, 'quantity', javascriptGenerator.ORDER_NONE) + const unit = javascriptGenerator.valueToCode(block, 'unit', javascriptGenerator.ORDER_NONE) + return [`${quantity}.toUnit(${unit})`, javascriptGenerator.ORDER_NONE] + } +} diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-valuestorage.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-valuestorage.js index 622d6c26a3..488a1257f3 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-valuestorage.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-valuestorage.js @@ -1,11 +1,13 @@ /* * These blocks allow values to be stored as "variables" in this.storedvars[] so they can "survive" when the rule is retriggered. * Note that the variables are only global to the individual rule not others. +* supports jsscripting */ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' -export default function defineOHBlocks_Variables (f7) { +export default function defineOHBlocks_Variables (f7, isGraalJs) { Blockly.Blocks['oh_store_value'] = { init: function () { this.appendDummyInput() @@ -15,22 +17,36 @@ export default function defineOHBlocks_Variables (f7) { this.appendDummyInput() .appendField('into') this.appendValueInput('key') + + if (isGraalJs) { + this.appendDummyInput() + .appendField('to ') + .appendField(new Blockly.FieldDropdown([['private', '.private'], ['shared', '.shared']]), 'cacheType') + .appendField('cache') + } this.setInputsInline(true) this.setPreviousStatement(true, null) this.setNextStatement(true, null) this.setColour(0) - this.setTooltip('stores a value with a variable name that can be retrieved on subsequent runs of this rule/script') + if (isGraalJs) { + this.setTooltip('stores a value with a variable name that can be retrieved on subsequent runs of this rule/script to the private rule or shared global cache') + } else { + this.setTooltip('stores a value with a variable name that can be retrieved on subsequent runs of this rule/script') + } this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-value-storage.html#store-value') } } - Blockly.JavaScript['oh_store_value'] = function (block) { - let key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC) - let value = Blockly.JavaScript.valueToCode(block, 'value', Blockly.JavaScript.ORDER_ATOMIC) - addStoredValues() - - let code = `this.storedValues[${key}] = ${value};\n` - return code + javascriptGenerator['oh_store_value'] = function (block) { + let key = javascriptGenerator.valueToCode(block, 'key', javascriptGenerator.ORDER_ATOMIC) + let value = javascriptGenerator.valueToCode(block, 'value', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + const cacheType = block.getFieldValue('cacheType') + return `cache${cacheType}.put(${key}, ${value});\n` + } else { + addStoredValues() + return `this.storedValues[${key}] = ${value};\n` + } } Blockly.Blocks['oh_get_value'] = { @@ -38,18 +54,32 @@ export default function defineOHBlocks_Variables (f7) { this.appendDummyInput() .appendField('stored value') this.appendValueInput('key') + if (isGraalJs) { + this.appendDummyInput() + .appendField('from ') + .appendField(new Blockly.FieldDropdown([['private', '.private'], ['shared', '.shared']]), 'cacheType') + .appendField('cache') + } this.setInputsInline(true) this.setOutput(true, null) this.setColour(0) - this.setTooltip('retrieves the value that was previously stored for that particular script/rule') + if (isGraalJs) { + this.setTooltip('retrieves the value that was previously stored for that particular script/rule from the private rule or shared global cache') + } else { + this.setTooltip('retrieves the value that was previously stored for that particular script/rule') + } this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-value-storage.html#get-stored-value') } } - Blockly.JavaScript['oh_get_value'] = function (block) { - let key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC) - let code = `this.storedValues[${key}]` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_get_value'] = function (block) { + let key = javascriptGenerator.valueToCode(block, 'key', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + const cacheType = block.getFieldValue('cacheType') + return [`cache${cacheType}.get(${key})`, javascriptGenerator.ORDER_NONE] + } else { + return [`this.storedValues[${key}]`, javascriptGenerator.ORDER_NONE] + } } Blockly.Blocks['oh_check_undefined_value'] = { @@ -57,22 +87,36 @@ export default function defineOHBlocks_Variables (f7) { this.appendValueInput('key') this.appendDummyInput() .appendField('is undefined') + if (isGraalJs) { + this.appendDummyInput() + .appendField('in ') + .appendField(new Blockly.FieldDropdown([['private', '.private'], ['shared', '.shared']]), 'cacheType') + .appendField('cache') + } this.setInputsInline(true) this.setOutput(true, null) this.setColour(0) - this.setTooltip('returns whether the given value is undefined') + if (isGraalJs) { + this.setTooltip('returns whether the given value is undefined in the private rule or shared global cache') + } else { + this.setTooltip('returns whether the given value is undefined') + } this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-value-storage.html#check-if-value-is-undefined') } } - Blockly.JavaScript['oh_check_undefined_value'] = function (block) { - let key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC) - let code = `typeof this.storedValues[${key}] === 'undefined'` - return [code, Blockly.JavaScript.ORDER_NONE] + javascriptGenerator['oh_check_undefined_value'] = function (block) { + let key = javascriptGenerator.valueToCode(block, 'key', javascriptGenerator.ORDER_ATOMIC) + if (isGraalJs) { + const cacheType = block.getFieldValue('cacheType') + return [`cache${cacheType}.exists(${key}) === false`, javascriptGenerator.ORDER_NONE] + } else { + return [`typeof this.storedValues[${key}] === 'undefined'`, javascriptGenerator.ORDER_NONE] + } } function addStoredValues () { let storedValues = 'if (typeof this.storedValues === \'undefined\') {\n this.storedValues = [];\n}' - Blockly.JavaScript.provideFunction_('storedValues', [storedValues]) + javascriptGenerator.provideFunction_('storedValues', [storedValues]) } } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js index 9d0b68dea5..56d9742ab9 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js @@ -14,27 +14,29 @@ import definePersistenceBlocks from './blocks-persistence' import defineColorBlocks from './blocks-color' import defineTextBlocks from './blocks-text' import defineListBlocks from './blocks-list' +import defineUomBlocks from './blocks-uom' import { defineLibraries } from './libraries' import Blockly from 'blockly' -export default function (f7, libraryDefinitions, data) { - defineDictionaryBlocks(f7) - defineDateOffsetsBlocks(f7) - defineItemBlocks(f7) - defineThingsBlocks(f7) - defineAudioBlocks(f7, data.sinks, data.voices) - defineEventBusBlocks(f7) - defineNotificationBlocks(f7) - defineLoggingBlocks(f7) - defineTimerBlocks(f7) - defineValueStorageBlocks(f7) - defineEphemerisBlocks(f7) - defineScriptsBlocks(f7) - definePersistenceBlocks(f7) - defineColorBlocks(f7) - defineTextBlocks(f7) - defineListBlocks(f7) +export default function (f7, libraryDefinitions, data, isGraalJs) { + defineDictionaryBlocks(f7, isGraalJs) + defineDateOffsetsBlocks(f7, isGraalJs) + defineItemBlocks(f7, isGraalJs) + defineThingsBlocks(f7, isGraalJs) + defineAudioBlocks(f7, isGraalJs, data.sinks, data.voices) + defineEventBusBlocks(f7, isGraalJs) + defineNotificationBlocks(f7, isGraalJs) + defineLoggingBlocks(f7, isGraalJs) + defineTimerBlocks(f7, isGraalJs) + defineValueStorageBlocks(f7, isGraalJs) + defineEphemerisBlocks(f7, isGraalJs) + defineScriptsBlocks(f7, isGraalJs) + definePersistenceBlocks(f7, isGraalJs) + defineColorBlocks(f7, isGraalJs) + defineTextBlocks(f7, isGraalJs) + defineListBlocks(f7, isGraalJs) + defineUomBlocks(f7, isGraalJs) defineLibraries(libraryDefinitions) } diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/libraries.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/libraries.js index 06478de752..a6fb30f779 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/libraries.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/libraries.js @@ -1,4 +1,5 @@ import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' import { addOSGiService } from './utils' const generateCodeForBlock = (block) => { @@ -16,7 +17,7 @@ const generateCodeForBlock = (block) => { } const provideUtility = (utilityName) => { - let utilityCode = [`function ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_}() { /* error! */ }`] + let utilityCode = [`function ${javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_}() { /* error! */ }`] if (library.slots.utilities) { const utilityComponent = library.slots.utilities.find(c => c.config && c.config.name === utilityName) if (!utilityComponent) { @@ -25,10 +26,10 @@ const generateCodeForBlock = (block) => { case 'UtilityFrameworkService': return addOSGiService(utilityName, utilityComponent.config.serviceClass) case 'UtilityJavaType': - utilityCode = `var ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_} = Java.type('${utilityComponent.config.javaClass}');` + utilityCode = `var ${javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_} = Java.type('${utilityComponent.config.javaClass}');` break default: - utilityCode = utilityComponent.config.code.replace('{{name}}', Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_) + utilityCode = utilityComponent.config.code.replace('{{name}}', javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_) // process additional utilities if referenced in the function code while (/(\{\{[A-Za-z0-9_]+\}\})/gm.test(utilityCode)) { const match = /(\{\{[A-Za-z0-9_:]+\}\})/gm.exec(utilityCode) @@ -43,7 +44,7 @@ const generateCodeForBlock = (block) => { } } - return Blockly.JavaScript.provideFunction_(utilityName, utilityCode.split('\n')) + return javascriptGenerator.provideFunction_(utilityName, utilityCode.split('\n')) } const processPlaceholder = (code, placeholder) => { @@ -55,8 +56,8 @@ const generateCodeForBlock = (block) => { context.fields[placeholderName] = block.getFieldValue(placeholderName) return code.replace(placeholder, context.fields[placeholderName]) case 'input': - const order = placeholderOption ? Blockly.JavaScript['ORDER_' + placeholderOption.replace('ORDER_', '')] : Blockly.JavaScript.ORDER_NONE - context.inputs[placeholderName] = Blockly.JavaScript.valueToCode(block, placeholderName, order) + const order = placeholderOption ? javascriptGenerator['ORDER_' + placeholderOption.replace('ORDER_', '')] : javascriptGenerator.ORDER_NONE + context.inputs[placeholderName] = javascriptGenerator.valueToCode(block, placeholderName, order) return code.replace(placeholder, context.inputs[placeholderName]) case 'utility': if (!context.utilities[placeholderName]) { @@ -66,12 +67,12 @@ const generateCodeForBlock = (block) => { case 'temp_name': if (!context.uniqueIdentifiers[placeholderName]) { const realm = placeholderOption ? Blockly.Variables[placeholderOption] : Blockly.Variables.NAME_TYPE - context.uniqueIdentifiers[placeholderName] = Blockly.JavaScript.variableDB_.getDistinctName(placeholderName, realm) + context.uniqueIdentifiers[placeholderName] = javascriptGenerator.variableDB_.getDistinctName(placeholderName, realm) } return code.replace(placeholder, context.uniqueIdentifiers[placeholderName]) case 'statements': if (!context.statements[placeholderName]) { - context.statements[placeholderName] = Blockly.JavaScript.statementToCode(block, placeholderName) + context.statements[placeholderName] = javascriptGenerator.statementToCode(block, placeholderName) } return code.replace(placeholder, context.statements[placeholderName].replace(/^ {2}/, '').trim()) default: @@ -82,7 +83,7 @@ const generateCodeForBlock = (block) => { if (!codeComponent || !codeComponent.config || !codeComponent.config.template) { if (block.outputConnection) { - return [`/* missing implementation for value block ${blockTypeId} */`, Blockly.JavaScript.ORDER_NONE] + return [`/* missing implementation for value block ${blockTypeId} */`, javascriptGenerator.ORDER_NONE] } else { return `/* missing implementation for statement block ${blockTypeId} */\n` } @@ -97,7 +98,7 @@ const generateCodeForBlock = (block) => { } if (block.outputConnection) { - const order = codeComponent.config.order ? Blockly.JavaScript[codeComponent.config.order] : Blockly.JavaScript.ORDER_NONE + const order = codeComponent.config.order ? javascriptGenerator[codeComponent.config.order] : javascriptGenerator.ORDER_NONE return [code, order] } else { return code @@ -171,7 +172,7 @@ export const defineLibraries = (libraryDefinitions) => { } } - Blockly.JavaScript[blockTypeId] = generateCodeForBlock + javascriptGenerator[blockTypeId] = generateCodeForBlock }) } }) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js index 92f6ef282a..58fa0c8e78 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js @@ -1,22 +1,22 @@ -import Blockly from 'blockly' +import { javascriptGenerator } from 'blockly/javascript' /* * Function allowing to call classes within the OSGi container * e.g. service -> 'ruleManager', class -> 'org.openhab.core.automation.RuleManager' */ export function addOSGiService (serviceName, serviceClass) { - const addServiceName = Blockly.JavaScript.provideFunction_( + const addServiceName = javascriptGenerator.provideFunction_( 'addFrameworkService', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' (serviceClass) {', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' (serviceClass) {', ' var bundleContext = Java.type(\'org.osgi.framework.FrameworkUtil\').getBundle(scriptExtension.class).getBundleContext();', ' var serviceReference = bundleContext.getServiceReference(serviceClass);', ' return bundleContext.getService(serviceReference);', '}' ]) - return Blockly.JavaScript.provideFunction_( + return javascriptGenerator.provideFunction_( serviceName, - [`var ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_} = ${addServiceName}('${serviceClass}');`]) + [`var ${javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_} = ${addServiceName}('${serviceClass}');`]) } /* @@ -34,17 +34,17 @@ export function addOSGiService (serviceName, serviceClass) { * - all of the above work with or without the "T" */ export function addDateSupport () { - let dtf = Blockly.JavaScript.provideFunction_( + let dtf = javascriptGenerator.provideFunction_( 'dtf', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.format.DateTimeFormatter");']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.format.DateTimeFormatter");']) - let zdt = Blockly.JavaScript.provideFunction_( + let zdt = javascriptGenerator.provideFunction_( 'zdt', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.ZonedDateTime");']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.ZonedDateTime");']) - let getzdt = Blockly.JavaScript.provideFunction_( + let getzdt = javascriptGenerator.provideFunction_( 'getZonedDateTime', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(datetime) {', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + '(datetime) {', ' datetime = String(datetime).replace(\'T\', \' \')', ' var regex_time_min = /^\\d{2}:\\d{2}$/;', ' var regex_time_sec = /^\\d{2}:\\d{2}:\\d{2}$/;', @@ -81,9 +81,9 @@ export function addDateSupport () { '}' ]) - let createzdt = Blockly.JavaScript.provideFunction_( + let createzdt = javascriptGenerator.provideFunction_( 'createZonedDateTime', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(year, month, day, hour, minute, second, nano, offsetString, timezoneString) {', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + '(year, month, day, hour, minute, second, nano, offsetString, timezoneString) {', ' stringToParse = \'\' + year;', ' stringToParse += \'-\' + (\'0\' + month).slice(-2);', ' stringToParse += \'-\' + (\'0\' + day).slice(-2);', @@ -91,7 +91,7 @@ export function addDateSupport () { ' stringToParse += \':\' + (\'0\' + minute).slice(-2);', ' stringToParse += \':\' + (\'0\' + second).slice(-2);', ' stringToParse += \'.\' + nano + offsetString + \'[\' + timezoneString + \']\';', - ` return ${zdt}.parse(stringToParse, dtf.ISO_ZONED_DATE_TIME);`, + ' return stringToParse;', '}' ]) @@ -99,9 +99,9 @@ export function addDateSupport () { } export function addGetZdtComponent () { - let getZdtComponent = Blockly.JavaScript.provideFunction_( + let getZdtComponent = javascriptGenerator.provideFunction_( 'getZdtComponent', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(value) {', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + '(value) {', ' return (typeof value == \'number\') ? value : value.getValue();', '}' ]) @@ -110,16 +110,17 @@ export function addGetZdtComponent () { } export function addChrono () { - let chrono = Blockly.JavaScript.provideFunction_( + let chrono = javascriptGenerator.provideFunction_( 'chrono', - ['var ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.temporal.ChronoField");']) + ['var ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + ' = Java.type("java.time.temporal.ChronoField");']) return chrono } -export function addDateComparisonSupport () { - let zdtCompare = Blockly.JavaScript.provideFunction_( +export function addDateComparisonSupportNashorn () { + let zdtCompare = javascriptGenerator.provideFunction_( 'zdtCompare', [ - 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(zdt1, zdt2, compareOp, precision, compDate) {', + '// Nashorn', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + '(zdt1, zdt2, compareOp, precision, compDate) {', ' switch (precision) {', ' case \'years\':', ' zdt2 = zdt2.withMonth(zdt1.getMonthValue());', @@ -157,3 +158,46 @@ export function addDateComparisonSupport () { ]) return zdtCompare } + +export function addDateComparisonSupportGraalVM () { + const graalZdtCompare = javascriptGenerator.provideFunction_( + 'zdtCompare', [ + '// graalVM', + 'function ' + javascriptGenerator.FUNCTION_NAME_PLACEHOLDER_ + '(zdt1, zdt2, compareOp, precision, compDate) {', + ' switch (precision) {', + ' case \'years\':', + ' zdt2 = zdt2.withMonth(zdt1.monthValue());', + ' case \'months\':', + ' zdt2 = zdt2.withDayOfMonth(zdt1.dayOfMonth());', + ' case \'days\':', + ' zdt2 = zdt2.withHour(zdt1.hour());', + ' case \'hours\':', + ' zdt2 = zdt2.withMinute(zdt1.minute());', + ' case \'minutes\':', + ' zdt2 = zdt2.withSecond(zdt1.second());', + ' case \'seconds\':', + ' zdt2 = zdt2.withNano(zdt1.nano());', + ' }', + ' if (compDate === \'date\') {', + ' zdt1 = zdt1.toLocalDate();', + ' zdt2 = zdt2.toLocalDate();', + ' } else if (compDate === \'time\') {', + ' zdt1 = zdt1.toLocalTime();', + ' zdt2 = zdt2.toLocalTime();', + ' }', + ' switch (compareOp) {', + ' case \'before\':', + ' return zdt1.isBefore(zdt2);', + ' case \'equal\':', + ' return zdt1.equals(zdt2);', + ' case \'after\':', + ' return zdt1.isAfter(zdt2);', + ' case \'beforeEqual\':', + ' return zdt1.isBefore(zdt2) || zdt1.equals(zdt2);', + ' case \'afterEqual\':', + ' return zdt1.isAfter(zdt2) || zdt1.equals(zdt2);', + ' }', + '}' + ]) + return graalZdtCompare +} diff --git a/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue b/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue index 36f266d532..5c89930c27 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue @@ -533,6 +533,41 @@ + + + + + 10 W + + + + + + + + + + + + + + + + + + + + + + + + + + kW + + + +