diff --git a/AzureDataStudioExtension/CHANGELOG.md b/AzureDataStudioExtension/CHANGELOG.md index 8687af2b..23fed47d 100644 --- a/AzureDataStudioExtension/CHANGELOG.md +++ b/AzureDataStudioExtension/CHANGELOG.md @@ -1,6 +1,37 @@ # Change Log -## [v7.6.1)(https://github.com/MarkMpn/Sql4Cds/releases/tag/v7.6.1) - 2023-10-15 +## [v8.0.0](https://github.com/MarkMpn/Sql4Cds/releases/tag/v8.0.0) - 2023-11-25 + +Added Common Table Expression support: +- Non-recursive CTEs are expanded to subqueries for compatibility with TDS Endpoint +- Recurve CTEs are converted to hierarchical FetchXML filters where possible + +Extended JSON support: +- `OPENJSON` table-valued function +- `JSON_QUERY` function +- `ISJSON` function + +Query optimizer improvements: +- Prefer hash joins over merge joins if sorts cannot be folded +- Switch FetchXML sorts to custom sorting after adding joins that require custom paging +- Avoid folding filters to tables in subqueries if the same alias exists in the outer query +- Do not use a left outer join to implement `NOT IN` queries where the subquery uses an inner join + +Added `IGNORE_DUP_KEY` query hint to ignore duplicate key errors on insert +Added check for multi-currency issues when aggregating non-base currency fields +Added support for disconnecting instances from Azure Data Studio object explorer +Added plugin log messages in error message output +Clearer progress messages for multi-threaded DML operations +Added autocomplete literal value suggestions for entityname attributes + +Fixed use of `UNION` with wildcard columns +Fixed error in nested loop joins with no records from inner source +Fixed use of columns from outer queries in join criteria in subqueries +Fixed time zone mismatch when starting bulk delete jobs +Fixed setting polymorphic lookup fields using TDS Endpoint +Fixed aggregates with very dense data distribution + +## [v7.6.1](https://github.com/MarkMpn/Sql4Cds/releases/tag/v7.6.1) - 2023-10-15 Fixed use of `IN` subqueries when data source cannot be converted to FetchXML Fixed use of `LIKE` filters with data containing embedded returns diff --git a/AzureDataStudioExtension/package-lock.json b/AzureDataStudioExtension/package-lock.json deleted file mode 100644 index 073b3572..00000000 --- a/AzureDataStudioExtension/package-lock.json +++ /dev/null @@ -1,11544 +0,0 @@ -{ - "name": "azuredatastudio-sql4cds", - "version": "4.9.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "azuredatastudio-sql4cds", - "version": "4.9.0", - "license": "MIT", - "dependencies": { - "@microsoft/ads-service-downloader": "1.0.2", - "crypto": "^1.0.1", - "dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.3.0", - "eventemitter2": "^5.0.1", - "opener": "^1.5.2", - "tmp": "0.2.1 ", - "vscode-extension-telemetry": "0.4.2", - "vscode-languageclient": "5.2.1" - }, - "devDependencies": { - "@types/azdata": "1.38.0", - "@types/node": "^13.11.0", - "@types/vscode": "^1.39.0", - "del": "^6.1.1", - "gulp": "github:gulpjs/gulp#4.0.2", - "gulp-json-editor": "^2.5.6", - "gulp-rename": "^2.0.0", - "gulp-shell": "^0.8.0", - "gulp-sourcemaps": "^3.0.0", - "gulp-tslint": "^8.1.4", - "gulp-typescript": "^5.0.1", - "tslint": "^6.1.3", - "typescript": "^4.8.3", - "vscode-nls-dev": "https://github.com/Raymondd/vscode-nls-dev/releases/download/2.0.2/build.tar.gz" - }, - "engines": { - "azdata": ">=1.40.0", - "vscode": "*" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "dependencies": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "dependencies": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/@microsoft/ads-service-downloader": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@microsoft/ads-service-downloader/-/ads-service-downloader-1.0.2.tgz", - "integrity": "sha512-Qpc5HNLywVZbSxeUC4S7d+VRAUddrYjkIfDXl76UwCA0iuwzi71RtciEgWfCWAZMm9CbKTIbtFGh4pYw+h81nQ==", - "dependencies": { - "async-retry": "^1.2.3", - "eventemitter2": "^5.0.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "mkdirp": "1.0.4", - "tar": "^6.1.11", - "tmp": "^0.0.33", - "yauzl": "^2.10.0" - } - }, - "node_modules/@microsoft/ads-service-downloader/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/azdata": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@types/azdata/-/azdata-1.38.0.tgz", - "integrity": "sha512-yXvy8+j2LgWoe7cX33doTDdv/0d7LMDEm3IfrXZ/EU4AwwzjvKqSR/0Ae0CH3o8WOvDm63bws++gxDlmhoLsPg==", - "dev": true, - "dependencies": { - "@types/vscode": "*" - } - }, - "node_modules/@types/fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "node_modules/@types/vscode": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.71.0.tgz", - "integrity": "sha512-nB50bBC9H/x2CpwW9FzRRRDrTZ7G0/POttJojvN/LiVfzTGfLyQIje1L1QRMdFXK9G41k5UJN/1B9S4of7CSzA==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/anymatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "dependencies": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "dependencies": { - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "dependencies": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "dependencies": { - "retry": "0.13.1" - } - }, - "node_modules/async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "dependencies": { - "async-done": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "dependencies": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha512-3vqtKL1N45I5dV0RdssXZG7X6pCqQrWPNOlBPZPrd+QkE2HEhR57Z04m0KtpbsZH73j+a3F8UD1TQnn+ExTvIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "dependencies": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "dependencies": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", - "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." - }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dataprotocol-client": { - "version": "0.3.0", - "resolved": "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/21487d15a5f753ba885ce1e489abc0af03487544", - "integrity": "sha512-QRQenym6p0KkXT8l/WRu86B8EkT9F5HzMuVzw0CFxpSr1zXjpxduAorvWI37amqWlMbS6MUVC1tLuMb11Ba7MA==", - "license": "ISC", - "dependencies": { - "vscode-languageclient": "3.5.1" - }, - "engines": { - "azdata": "*", - "vscode": "*" - } - }, - "node_modules/dataprotocol-client/node_modules/vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha512-LeE9LS1IOIRDZy5Xugrbk2tKeMa64vkRODrXPZbwyn2l/Q0e/jyYq8ze/Lo96sjOFiRe3HHbTVN39Ta8KN2RpA==", - "engines": { - "node": ">=4.0.0 || >=6.0.0" - } - }, - "node_modules/dataprotocol-client/node_modules/vscode-languageclient": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.1.tgz", - "integrity": "sha512-GTQ+hSq/o4c/y6GYmyP9XNrVoIu0NFZ67KltSkqN+tO0eUNDIlrVNX+3DJzzyLhSsrctuGzuYWm3t87mNAcBmQ==", - "dependencies": { - "vscode-languageserver-protocol": "3.5.1" - }, - "engines": { - "vscode": "^1.15" - } - }, - "node_modules/dataprotocol-client/node_modules/vscode-languageserver-protocol": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", - "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", - "dependencies": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" - } - }, - "node_modules/dataprotocol-client/node_modules/vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha512-D4rUfu/oKYdc9Tmec0nEfedj+uXO2tZHR+eoHs9rE9G/QpRyZaHuug8ZUNGTGdO+ALLGgenL6bRpY8y3J9acHg==" - }, - "node_modules/dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "dependencies": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "dependencies": { - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", - "dev": true, - "dependencies": { - "readable-stream": "~1.1.9" - } - }, - "node_modules/duplexer2/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "node_modules/each-props/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "dependencies": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "bin": { - "editorconfig": "bin/editorconfig" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, - "node_modules/eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/findup-sync/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fined/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/glob-stream/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/gulp": { - "version": "4.0.2", - "resolved": "https://codeload.github.com/gulpjs/gulp/tar.gz/069350a5febf65adc27bc816a7805471b7d96f03", - "integrity": "sha512-XrrOLkWNFDZi86El7qJyrou/+YzBzZ5B9h0Nhswn3FIoMY1cJG8H/WXy0BW0OE+sN1xYNQoC3Q8hflCxnrrEBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-json-editor": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.5.6.tgz", - "integrity": "sha512-66Xr6Q6m4mUNd0OOHflMB/RHgFNnLjlHgizOzUcx9CyMRymVZEM+/SpZcCDlvThBdXtQwXpdvtSepxVY/V6nQA==", - "dev": true, - "dependencies": { - "deepmerge": "^4.2.2", - "detect-indent": "^6.0.0", - "js-beautify": "^1.13.13", - "plugin-error": "^1.0.1", - "through2": "^4.0.2" - } - }, - "node_modules/gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gulp-shell": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.8.0.tgz", - "integrity": "sha512-wHNCgmqbWkk1c6Gc2dOL5SprcoeujQdeepICwfQRo91DIylTE7a794VEE+leq3cE2YDoiS5ulvRfKVIEMazcTQ==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "fancy-log": "^1.3.3", - "lodash.template": "^4.5.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "tslib": "^1.10.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/gulp-shell/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "dependencies": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/gulp-sourcemaps/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-tslint": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/gulp-tslint/-/gulp-tslint-8.1.4.tgz", - "integrity": "sha512-wBoZIEMJRz9urHwolsvQpngA9l931p6g/Liwz1b/KrsVP6jEBFZv/o0NS1TFCQZi/l8mXxz8+v3twhf4HOXxPQ==", - "dev": true, - "dependencies": { - "@types/fancy-log": "1.3.0", - "ansi-colors": "^1.0.1", - "fancy-log": "1.3.3", - "map-stream": "~0.0.7", - "plugin-error": "1.0.1", - "through": "~2.3.8" - }, - "engines": { - "node": ">= 4" - }, - "peerDependencies": { - "tslint": ">=5.0.0-dev" - } - }, - "node_modules/gulp-typescript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", - "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", - "dev": true, - "dependencies": { - "ansi-colors": "^3.0.5", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.3" - }, - "engines": { - "node": ">= 8" - }, - "peerDependencies": { - "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" - } - }, - "node_modules/gulp-typescript/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/gulp-typescript/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/gulp-typescript/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha512-q5oWPc12lwSFS9h/4VIjG+1NuNDlJ48ywV2JKItY4Ycc/n1fXJeYPVQsfu5ZrhQi7FGSDBalwUCLar/GyHXKGw==", - "deprecated": "gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5", - "dev": true, - "dependencies": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/gulp-util/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-util/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-util/node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/gulp-util/node_modules/clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", - "dev": true - }, - "node_modules/gulp-util/node_modules/object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-util/node_modules/replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gulp-util/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/gulp-util/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-util/node_modules/vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha512-P5zdf3WB9uzr7IFoVQ2wZTmUwHL8cMZWJGzLBNCHNZ3NB6HTMsYABtt7z8tAGIINLXyAob9B9a1yzVGMFOYKEA==", - "dev": true, - "dependencies": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - }, - "engines": { - "node": ">= 0.9" - } - }, - "node_modules/gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "dependencies": { - "glogg": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dependencies": { - "agent-base": "4", - "debug": "3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-beautify": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", - "integrity": "sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==", - "dev": true, - "dependencies": { - "config-chain": "^1.1.13", - "editorconfig": "^0.15.3", - "glob": "^8.0.3", - "nopt": "^6.0.0" - }, - "bin": { - "css-beautify": "js/bin/css-beautify.js", - "html-beautify": "js/bin/html-beautify.js", - "js-beautify": "js/bin/js-beautify.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "dependencies": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "dependencies": { - "flush-write-stream": "^1.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/liftoff/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha512-Sjlavm5y+FUVIF3vF3B75GyXrzsfYV8Dlv3L4mEpuB9leg8N6yf/7rU06iLPx9fY0Mv3khVp9p7Dx0mGV6V5OQ==", - "dev": true - }, - "node_modules/lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha512-OrPwdDc65iJiBeUe5n/LIjd7Viy99bKwDdk7Z5ljfZg0uFRFlfQaCy9tZ4YMAag9WAZmlVpe1iZrkIMMSMHD3w==", - "dev": true - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.2" - } - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "dependencies": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/matchdep/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/matchdep/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/micromatch/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/micromatch/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/micromatch/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==", - "dev": true, - "dependencies": { - "duplexer2": "0.0.2" - } - }, - "node_modules/mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "dev": true, - "optional": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "dependencies": { - "once": "^1.3.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "dependencies": { - "path-root-regex": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/plugin-error/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plugin-error/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plugin-error/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/readdirp/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "dependencies": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-bom-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "dependencies": { - "value-or-function": "^3.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "dependencies": { - "sver-compat": "^1.5.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "dependencies": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/through2-filter/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "dependencies": { - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/to-through/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" - } - }, - "node_modules/tslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/tslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/tslint/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/tslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "dependencies": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "dependencies": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-sourcemap/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vscode-extension-telemetry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.4.2.tgz", - "integrity": "sha512-y0f51mVoFxHIzULQNCC26TBFIKdEC7uckS3tFoK++OOOl8mU2LlOxgmbd52T/SXoXNg5aI7xqs+4V2ug5ITvKw==", - "deprecated": "This package has been renamed to @vscode/extension-telemetry, please update to the new name", - "engines": { - "vscode": "^1.60.0" - } - }, - "node_modules/vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "engines": { - "node": ">=8.0.0 || >=10.0.0" - } - }, - "node_modules/vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "dependencies": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "engines": { - "vscode": "^1.30" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dependencies": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "node_modules/vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - }, - "node_modules/vscode-nls-dev": { - "version": "2.0.1", - "resolved": "https://github.com/Raymondd/vscode-nls-dev/releases/download/2.0.2/build.tar.gz", - "integrity": "sha512-U8SoBs3upxlVvuxNNQqZJilypQsd4a7rRdHllp3NRKAZGzL8SXLoICZBCKpFDfmGKEAYYdTogf8iOB3CD78UaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2", - "event-stream": "^3.3.2", - "glob": "^6.0.4", - "gulp-util": "^3.0.7", - "source-map": "^0.5.3", - "typescript": "^2.0.3", - "vinyl": "^1.1.1", - "yargs": "^3.32.0" - }, - "bin": { - "vscl": "lib/vscl.js" - } - }, - "node_modules/vscode-nls-dev/node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vscode-nls-dev/node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/vscode-nls-dev/node_modules/clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", - "dev": true - }, - "node_modules/vscode-nls-dev/node_modules/glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/vscode-nls-dev/node_modules/replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/vscode-nls-dev/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vscode-nls-dev/node_modules/typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/vscode-nls-dev/node_modules/vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha512-Ci3wnR2uuSAWFMSglZuB8Z2apBdtOyz8CV7dC6/U1XbltXBC+IuutUkXQISz01P+US2ouBuesSbV6zILZ6BuzQ==", - "dev": true, - "dependencies": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - }, - "engines": { - "node": ">= 0.9" - } - }, - "node_modules/vscode-nls-dev/node_modules/yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", - "dev": true, - "dependencies": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "node_modules/window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, - "node_modules/yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "node_modules/yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "requires": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "dependencies": { - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "@microsoft/ads-service-downloader": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@microsoft/ads-service-downloader/-/ads-service-downloader-1.0.2.tgz", - "integrity": "sha512-Qpc5HNLywVZbSxeUC4S7d+VRAUddrYjkIfDXl76UwCA0iuwzi71RtciEgWfCWAZMm9CbKTIbtFGh4pYw+h81nQ==", - "requires": { - "async-retry": "^1.2.3", - "eventemitter2": "^5.0.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "mkdirp": "1.0.4", - "tar": "^6.1.11", - "tmp": "^0.0.33", - "yauzl": "^2.10.0" - }, - "dependencies": { - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@types/azdata": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@types/azdata/-/azdata-1.38.0.tgz", - "integrity": "sha512-yXvy8+j2LgWoe7cX33doTDdv/0d7LMDEm3IfrXZ/EU4AwwzjvKqSR/0Ae0CH3o8WOvDm63bws++gxDlmhoLsPg==", - "dev": true, - "requires": { - "@types/vscode": "*" - } - }, - "@types/fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw==", - "dev": true - }, - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "@types/vscode": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.71.0.tgz", - "integrity": "sha512-nB50bBC9H/x2CpwW9FzRRRDrTZ7G0/POttJojvN/LiVfzTGfLyQIje1L1QRMdFXK9G41k5UJN/1B9S4of7CSzA==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "requires": { - "retry": "0.13.1" - } - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha512-3vqtKL1N45I5dV0RdssXZG7X6pCqQrWPNOlBPZPrd+QkE2HEhR57Z04m0KtpbsZH73j+a3F8UD1TQnn+ExTvIA==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, - "copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "requires": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" - }, - "css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dataprotocol-client": { - "version": "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/21487d15a5f753ba885ce1e489abc0af03487544", - "integrity": "sha512-QRQenym6p0KkXT8l/WRu86B8EkT9F5HzMuVzw0CFxpSr1zXjpxduAorvWI37amqWlMbS6MUVC1tLuMb11Ba7MA==", - "requires": { - "vscode-languageclient": "3.5.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha512-LeE9LS1IOIRDZy5Xugrbk2tKeMa64vkRODrXPZbwyn2l/Q0e/jyYq8ze/Lo96sjOFiRe3HHbTVN39Ta8KN2RpA==" - }, - "vscode-languageclient": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.1.tgz", - "integrity": "sha512-GTQ+hSq/o4c/y6GYmyP9XNrVoIu0NFZ67KltSkqN+tO0eUNDIlrVNX+3DJzzyLhSsrctuGzuYWm3t87mNAcBmQ==", - "requires": { - "vscode-languageserver-protocol": "3.5.1" - } - }, - "vscode-languageserver-protocol": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", - "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", - "requires": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" - } - }, - "vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha512-D4rUfu/oKYdc9Tmec0nEfedj+uXO2tZHR+eoHs9rE9G/QpRyZaHuug8ZUNGTGdO+ALLGgenL6bRpY8y3J9acHg==" - } - } - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==", - "dev": true - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "requires": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true - }, - "detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", - "dev": true, - "requires": { - "readable-stream": "~1.1.9" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - } - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "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 - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, - "eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "requires": { - "pend": "~1.2.0" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "gulp": { - "version": "https://codeload.github.com/gulpjs/gulp/tar.gz/069350a5febf65adc27bc816a7805471b7d96f03", - "integrity": "sha512-XrrOLkWNFDZi86El7qJyrou/+YzBzZ5B9h0Nhswn3FIoMY1cJG8H/WXy0BW0OE+sN1xYNQoC3Q8hflCxnrrEBw==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - } - }, - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - }, - "gulp-json-editor": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.5.6.tgz", - "integrity": "sha512-66Xr6Q6m4mUNd0OOHflMB/RHgFNnLjlHgizOzUcx9CyMRymVZEM+/SpZcCDlvThBdXtQwXpdvtSepxVY/V6nQA==", - "dev": true, - "requires": { - "deepmerge": "^4.2.2", - "detect-indent": "^6.0.0", - "js-beautify": "^1.13.13", - "plugin-error": "^1.0.1", - "through2": "^4.0.2" - } - }, - "gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true - }, - "gulp-shell": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.8.0.tgz", - "integrity": "sha512-wHNCgmqbWkk1c6Gc2dOL5SprcoeujQdeepICwfQRo91DIylTE7a794VEE+leq3cE2YDoiS5ulvRfKVIEMazcTQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "fancy-log": "^1.3.3", - "lodash.template": "^4.5.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-tslint": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/gulp-tslint/-/gulp-tslint-8.1.4.tgz", - "integrity": "sha512-wBoZIEMJRz9urHwolsvQpngA9l931p6g/Liwz1b/KrsVP6jEBFZv/o0NS1TFCQZi/l8mXxz8+v3twhf4HOXxPQ==", - "dev": true, - "requires": { - "@types/fancy-log": "1.3.0", - "ansi-colors": "^1.0.1", - "fancy-log": "1.3.3", - "map-stream": "~0.0.7", - "plugin-error": "1.0.1", - "through": "~2.3.8" - } - }, - "gulp-typescript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", - "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.5", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.3" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha512-q5oWPc12lwSFS9h/4VIjG+1NuNDlJ48ywV2JKItY4Ycc/n1fXJeYPVQsfu5ZrhQi7FGSDBalwUCLar/GyHXKGw==", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha512-P5zdf3WB9uzr7IFoVQ2wZTmUwHL8cMZWJGzLBNCHNZ3NB6HTMsYABtt7z8tAGIINLXyAob9B9a1yzVGMFOYKEA==", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "js-beautify": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", - "integrity": "sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==", - "dev": true, - "requires": { - "config-chain": "^1.1.13", - "editorconfig": "^0.15.3", - "glob": "^8.0.3", - "nopt": "^6.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha512-Sjlavm5y+FUVIF3vF3B75GyXrzsfYV8Dlv3L4mEpuB9leg8N6yf/7rU06iLPx9fY0Mv3khVp9p7Dx0mGV6V5OQ==", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha512-OrPwdDc65iJiBeUe5n/LIjd7Viy99bKwDdk7Z5ljfZg0uFRFlfQaCy9tZ4YMAag9WAZmlVpe1iZrkIMMSMHD3w==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - } - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "requires": { - "abbrev": "^1.0.0" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "requires": { - "through": "2" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - } - }, - "stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true - }, - "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "vscode-extension-telemetry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.4.2.tgz", - "integrity": "sha512-y0f51mVoFxHIzULQNCC26TBFIKdEC7uckS3tFoK++OOOl8mU2LlOxgmbd52T/SXoXNg5aI7xqs+4V2ug5ITvKw==" - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - }, - "vscode-nls-dev": { - "version": "https://github.com/Raymondd/vscode-nls-dev/releases/download/2.0.2/build.tar.gz", - "integrity": "sha512-U8SoBs3upxlVvuxNNQqZJilypQsd4a7rRdHllp3NRKAZGzL8SXLoICZBCKpFDfmGKEAYYdTogf8iOB3CD78UaQ==", - "dev": true, - "requires": { - "clone": "^1.0.2", - "event-stream": "^3.3.2", - "glob": "^6.0.4", - "gulp-util": "^3.0.7", - "source-map": "^0.5.3", - "typescript": "^2.0.3", - "vinyl": "^1.1.1", - "yargs": "^3.32.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", - "dev": true - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", - "dev": true - }, - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha512-Ci3wnR2uuSAWFMSglZuB8Z2apBdtOyz8CV7dC6/U1XbltXBC+IuutUkXQISz01P+US2ouBuesSbV6zILZ6BuzQ==", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } -} diff --git a/AzureDataStudioExtension/package.json b/AzureDataStudioExtension/package.json index 31c3b023..ff6058a2 100644 --- a/AzureDataStudioExtension/package.json +++ b/AzureDataStudioExtension/package.json @@ -352,7 +352,7 @@ "@types/vscode": "1.71.0", "@types/azdata": "1.40.0", "del": "^6.1.1", - "gulp": "github:gulpjs/gulp#4.0.2", + "gulp": "github:gulpjs/gulp#v4.0.2", "gulp-json-editor": "^2.5.6", "gulp-rename": "^2.0.0", "gulp-shell": "^0.8.0", diff --git a/AzureDataStudioExtension/src/main.ts b/AzureDataStudioExtension/src/main.ts index 3ec73b7d..010cb023 100644 --- a/AzureDataStudioExtension/src/main.ts +++ b/AzureDataStudioExtension/src/main.ts @@ -71,9 +71,9 @@ export async function activate(context: vscode.ExtensionContext) { }); languageClient.onNotification("sql4cds/confirmation", (message: {ownerUri: string, msg: string}) => { vscode.window - .showInformationMessage(message.msg, "Yes", "No") + .showInformationMessage(message.msg, "Yes", "All", "No") .then(answer => { - languageClient.sendNotification("sql4cds/confirm", { ownerUri: message.ownerUri, result: answer === "Yes" }) + languageClient.sendNotification("sql4cds/confirm", { ownerUri: message.ownerUri, result: answer }) }); }); languageClient.onNotification("query/batchComplete", () => { diff --git a/AzureDataStudioExtension/yarn.lock b/AzureDataStudioExtension/yarn.lock index 20c29262..a7967127 100644 --- a/AzureDataStudioExtension/yarn.lock +++ b/AzureDataStudioExtension/yarn.lock @@ -64,7 +64,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -79,7 +79,7 @@ "@types/azdata@1.40.0": version "1.40.0" - resolved "https://registry.yarnpkg.com/@types/azdata/-/azdata-1.40.0.tgz#0a454d9261a6eadbb70692515184bcea5bbb9d61" + resolved "https://registry.npmjs.org/@types/azdata/-/azdata-1.40.0.tgz" integrity sha512-CGsuH9wY6616UGskR1bMd3KcOTHhh43dQz9ruSji3EmzUG6EYJCE+6D3+UZ6M+Ub73XzDeYXobe/rk+fGkaYlg== dependencies: "@types/vscode" "*" @@ -96,7 +96,7 @@ "@types/vscode@*", "@types/vscode@1.71.0": version "1.71.0" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.71.0.tgz#a8d9bb7aca49b0455060e6eb978711b510bdd2e2" + resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.71.0.tgz" integrity sha512-nB50bBC9H/x2CpwW9FzRRRDrTZ7G0/POttJojvN/LiVfzTGfLyQIje1L1QRMdFXK9G41k5UJN/1B9S4of7CSzA== abbrev@^1.0.0: @@ -109,7 +109,7 @@ acorn@^6.4.1: resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -agent-base@4, agent-base@^4.3.0: +agent-base@^4.3.0, agent-base@4: version "4.3.0" resolved "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== @@ -143,10 +143,10 @@ ansi-gray@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-regex@^2.0.0, ansi-regex@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== ansi-styles@^2.2.1: version "2.2.1" @@ -167,7 +167,7 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: +ansi-wrap@^0.1.0, ansi-wrap@0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz" integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== @@ -341,11 +341,6 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - base@^0.11.1: version "0.11.2" resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" @@ -369,21 +364,6 @@ binary-extensions@^1.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bl@^1.0.0, bl@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -392,6 +372,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" @@ -415,19 +402,6 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" @@ -438,24 +412,11 @@ buffer-equal@^1.0.0: resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.2.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" @@ -505,7 +466,16 @@ chalk@^1.0.0: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.3.0: +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^2.3.0: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -640,24 +610,24 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-support@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -commander@^2.12.1, commander@^2.19.0, commander@^2.8.1: +commander@^2.12.1, commander@^2.19.0: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== component-emitter@^1.2.1: @@ -700,9 +670,9 @@ copy-descriptor@^0.1.0: resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -copy-props@^2.0.1, copy-props@^2.0.5: +copy-props@^2.0.1: version "2.0.5" - resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + resolved "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz" integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== dependencies: each-props "^1.3.2" @@ -727,7 +697,7 @@ css@^3.0.0: source-map "^0.6.1" source-map-resolve "^0.6.0" -d@1, d@^1.0.1: +d@^1.0.1, d@1: version "1.0.1" resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz" integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== @@ -737,7 +707,7 @@ d@1, d@^1.0.1: "dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#1.3.1": version "1.3.1" - resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/2df6982e07c0208c2b8a5f8cd4b3d65944138d15" + resolved "git+ssh://git@github.com/Microsoft/sqlops-dataprotocolclient.git#2df6982e07c0208c2b8a5f8cd4b3d65944138d15" dependencies: vscode-languageclient "5.2.1" @@ -755,24 +725,31 @@ debug-fabulous@^1.0.0: memoizee "0.4.X" object-assign "4.X" -debug@3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^2.3.3: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@3.X, debug@^3.1.0: +debug@^3.1.0, debug@3.X: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" @@ -786,59 +763,6 @@ decode-uri-component@^0.2.0: resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== -decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== - dependencies: - file-type "^5.2.0" - is-stream "^1.1.0" - tar-stream "^1.5.2" - -decompress-tarbz2@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== - dependencies: - decompress-tar "^4.1.0" - file-type "^6.1.0" - is-stream "^1.1.0" - seek-bzip "^1.0.5" - unbzip2-stream "^1.0.9" - -decompress-targz@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== - dependencies: - decompress-tar "^4.1.1" - file-type "^5.2.0" - is-stream "^1.1.0" - -decompress-unzip@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== - dependencies: - file-type "^3.8.0" - get-stream "^2.2.0" - pify "^2.3.0" - yauzl "^2.4.2" - -decompress@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" - integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== - dependencies: - decompress-tar "^4.0.0" - decompress-tarbz2 "^4.0.0" - decompress-targz "^4.0.0" - decompress-unzip "^4.0.1" - graceful-fs "^4.1.10" - make-dir "^1.0.0" - pify "^2.3.0" - strip-dirs "^2.0.0" - deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" @@ -927,6 +851,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + duplexer2@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz" @@ -934,11 +863,6 @@ duplexer2@0.0.2: dependencies: readable-stream "~1.1.9" -duplexer@^0.1.1, duplexer@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - duplexify@^3.6.0: version "3.7.1" resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz" @@ -1099,7 +1023,15 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend-shallow@^3.0.0, extend-shallow@^3.0.2: +extend-shallow@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== @@ -1126,7 +1058,7 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fancy-log@1.3.3, fancy-log@^1.1.0, fancy-log@^1.3.2, fancy-log@^1.3.3: +fancy-log@^1.1.0, fancy-log@^1.3.2, fancy-log@^1.3.3, fancy-log@1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz" integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== @@ -1166,26 +1098,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== - -file-type@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== - -file-type@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" @@ -1279,11 +1191,6 @@ from@^0.1.7: resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz" integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" @@ -1304,14 +1211,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" @@ -1331,20 +1230,20 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.3" -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== -glob-parent@^3.1.0, glob-parent@^5.1.2: +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1391,7 +1290,19 @@ glob@^6.0.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@^7.1.3: +glob@^7.1.1: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -1453,14 +1364,14 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: version "4.2.10" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -gulp-cli@^2.2.0, gulp-cli@^2.3.0: +gulp-cli@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + resolved "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz" integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== dependencies: ansi-colors "^1.0.1" @@ -1575,9 +1486,9 @@ gulp-util@^3.0.7: through2 "^2.0.0" vinyl "^0.5.0" -"gulp@github:gulpjs/gulp#4.0.2": +"gulp@github:gulpjs/gulp#v4.0.2": version "4.0.2" - resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/069350a5febf65adc27bc816a7805471b7d96f03" + resolved "git+ssh://git@github.com/gulpjs/gulp.git#069350a5febf65adc27bc816a7805471b7d96f03" dependencies: glob-watcher "^5.0.3" gulp-cli "^2.2.0" @@ -1672,9 +1583,9 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.8.9: +hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== http-proxy-agent@^2.1.0: @@ -1693,11 +1604,6 @@ https-proxy-agent@^2.2.3: agent-base "^4.3.0" debug "^3.1.0" -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" @@ -1716,14 +1622,14 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@2: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.4, ini@^1.3.6: +ini@^1.3.4: version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== interpret@^1.4.0: @@ -1805,7 +1711,16 @@ is-descriptor@^0.1.0: is-data-descriptor "^0.1.4" kind-of "^5.0.0" -is-descriptor@^1.0.0, is-descriptor@^1.0.2: +is-descriptor@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== @@ -1852,11 +1767,6 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-natural-number@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" - integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== - is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz" @@ -1889,7 +1799,21 @@ is-path-inside@^3.0.2: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.1: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -1913,11 +1837,6 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== - is-unc-path@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz" @@ -1940,16 +1859,16 @@ is-windows@^1.0.1, is-windows@^1.0.2: resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +isarray@~1.0.0, isarray@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isarray@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -2000,9 +1919,47 @@ just-debounce@^1.0.0: resolved "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz" integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^4.0.0, kind-of@^5.0.0, kind-of@^5.0.2, kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^3.0.3: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== last-run@^1.1.0: @@ -2059,6 +2016,31 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz" + integrity sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ== + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz" + integrity sha512-mTzAr1aNAv/i7W43vOR/uD/aJ4ngbtsRaCubp2BfZhlGU/eORUjg/7F6X0orNMdv33JOrdgGybtvMN/po3EWrA== + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz" + integrity sha512-H94wl5P13uEqlCg7OcNNhMQ8KvWSIyqXzOPusRgHC9DK3o54P6P3xtbXlVbRABG4q5gSmp7EDdJ0MSuW9HX6Mg== + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" + integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" + integrity sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ== + lodash._reescape@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz" @@ -2074,7 +2056,58 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== -lodash.template@^3.0.0, lodash.template@^4.5.0: +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz" + integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ== + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz" + integrity sha512-n1PZMXgaaDWZDSvuNZ/8XOcYO2hOKDqZel5adtR30VKQAtoWs/5AOeFA0vPV8moiPzlqe7F4cP2tzpFewQyelQ== + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" + integrity sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ== + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" + integrity sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ== + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz" + integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz" + integrity sha512-0B4Y53I0OgHUJkt+7RmlDFWKjVAI/YUpWNiL9GQz5ORDr4ttgfQGo+phBWKFLJbBdtOwgMuUkdOHOnPg45jKmQ== + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== @@ -2082,6 +2115,14 @@ lodash.template@^3.0.0, lodash.template@^4.5.0: lodash._reinterpolate "^3.0.0" lodash.templatesettings "^4.0.0" +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz" + integrity sha512-TcrlEr31tDYnWkHFWDCV3dHYroKEXpJZ2YJYvJdhN+y4AkWMDZ5I4I8XDtUKqSAyG81N7w+I1mFEJtcED+tGqQ== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.templatesettings@^4.0.0: version "4.2.0" resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz" @@ -2104,13 +2145,6 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - make-iterator@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz" @@ -2123,7 +2157,7 @@ map-cache@^0.2.0, map-cache@^0.2.2: resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== -map-stream@0.0.7, map-stream@~0.0.7: +map-stream@~0.0.7, map-stream@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz" integrity sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ== @@ -2164,7 +2198,45 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.0.4: + version "3.1.10" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^3.1.4: version "3.1.10" resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -2191,17 +2263,24 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^5.0.1: +minimatch@^3.0.4, minimatch@^3.1.1, "minimatch@2 || 3": version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimist@^1.1.0, minimist@^1.2.3, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.1.0, minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== minipass@^3.0.0: version "3.3.4" @@ -2218,19 +2297,14 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mixin-deep@^1.2.0, mixin-deep@^1.3.2: +mixin-deep@^1.2.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@1.0.4, mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - mkdirp@^0.5.3: version "0.5.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" @@ -2238,16 +2312,21 @@ mkdirp@^0.5.3: dependencies: minimist "^1.2.6" -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +mkdirp@^1.0.3, mkdirp@1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== ms@^2.1.1: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + multipipe@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz" @@ -2260,11 +2339,6 @@ mute-stdout@^1.0.0: resolved "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -nan@^2.12.1: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" @@ -2282,7 +2356,7 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -next-tick@1, next-tick@^1.1.0: +next-tick@^1.1.0, next-tick@1: version "1.1.0" resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== @@ -2304,7 +2378,14 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== @@ -2328,16 +2409,16 @@ number-is-nan@^1.0.0: resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== -object-assign@4.X, object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - object-assign@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" integrity sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ== +object-assign@4.X: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" @@ -2471,6 +2552,11 @@ pascalcase@^0.1.1: resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" @@ -2536,16 +2622,11 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.0.0, pify@^2.3.0: +pify@^2.0.0: version "2.3.0" resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" @@ -2558,7 +2639,7 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== -plugin-error@1.0.1, plugin-error@^1.0.1: +plugin-error@^1.0.1, plugin-error@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz" integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== @@ -2640,7 +2721,7 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@2 || 3", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6, "readable-stream@2 || 3": version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -2653,15 +2734,6 @@ read-pkg@^1.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@3: - version "3.6.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" @@ -2672,6 +2744,15 @@ readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@3: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" @@ -2728,16 +2809,16 @@ repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz" - integrity sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ== - replace-ext@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz" integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz" + integrity sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ== + replace-homedir@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz" @@ -2820,11 +2901,6 @@ safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" @@ -2832,13 +2908,6 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -seek-bzip@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" - integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== - dependencies: - commander "^2.8.1" - semver-greatest-satisfied-range@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz" @@ -2846,7 +2915,7 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: +semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, "semver@2 || 3 || 4 || 5": version "5.7.1" resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2930,7 +2999,12 @@ source-map-url@^0.4.0: resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== -source-map@^0.5.3, source-map@^0.5.6: +source-map@^0.5.3: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.5.6: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -3026,15 +3100,6 @@ stream-shift@^1.0.0: resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - string_decoder@^1.1.1, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" @@ -3047,6 +3112,15 @@ string_decoder@~0.10.x: resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" @@ -3066,13 +3140,6 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-dirs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== - dependencies: - is-natural-number "^4.0.1" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" @@ -3105,19 +3172,6 @@ sver-compat@^1.5.0: es6-iterator "^2.0.1" es6-symbol "^3.1.1" -tar-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - tar@^6.1.11: version "6.1.11" resolved "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz" @@ -3130,6 +3184,11 @@ tar@^6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" +through@^2.3.8, through@~2.3, through@~2.3.4, through@~2.3.8, through@2: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + through2-filter@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz" @@ -3138,7 +3197,15 @@ through2-filter@^3.0.0: through2 "~2.0.0" xtend "~4.0.0" -through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^2.0.3: version "2.0.5" resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -3146,7 +3213,15 @@ through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through2@^3.0.0, through2@^3.0.1: +through2@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + +through2@^3.0.1: version "3.0.2" resolved "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz" integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== @@ -3161,10 +3236,13 @@ through2@^4.0.2: dependencies: readable-stream "3" -through@2, through@^2.3.8, through@~2.3, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +through2@~2.0.0: + version "2.0.5" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" time-stamp@^1.0.0: version "1.1.0" @@ -3179,13 +3257,6 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" -"tmp@0.2.1 ": - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - tmp@^0.0.33: version "0.0.33" resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" @@ -3193,6 +3264,13 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +"tmp@0.2.1 ": + version "0.2.1" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + to-absolute-glob@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz" @@ -3201,11 +3279,6 @@ to-absolute-glob@^2.0.0: is-absolute "^1.0.0" is-negated-glob "^1.0.0" -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" @@ -3250,7 +3323,7 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslint@^6.1.3: +tslint@^6.1.3, tslint@>=5.0.0-dev: version "6.1.3" resolved "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz" integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== @@ -3296,19 +3369,11 @@ typescript@^2.0.3: resolved "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz" integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== -typescript@^4.8.3: +typescript@^4.8.3, "typescript@>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev", "typescript@>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev", "typescript@~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev": version "4.8.4" resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz" integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== -unbzip2-stream@^1.0.9: - version "1.4.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz" @@ -3474,12 +3539,12 @@ vscode-extension-telemetry@0.4.2: vscode-jsonrpc@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" + resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== vscode-languageclient@5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193" + resolved "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz" integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q== dependencies: semver "^5.5.0" @@ -3487,7 +3552,7 @@ vscode-languageclient@5.2.1: vscode-languageserver-protocol@3.14.1: version "3.14.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" + resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz" integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== dependencies: vscode-jsonrpc "^4.0.0" @@ -3495,7 +3560,7 @@ vscode-languageserver-protocol@3.14.1: vscode-languageserver-types@3.14.0: version "3.14.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz" integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== "vscode-nls-dev@https://github.com/Raymondd/vscode-nls-dev/releases/download/2.0.2/build.tar.gz": @@ -3542,14 +3607,14 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: +xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -y18n@^3.2.0, y18n@^3.2.1, y18n@^3.2.2: +y18n@^3.2.0, y18n@^3.2.1: version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== yallist@^2.1.2: @@ -3602,9 +3667,9 @@ yargs@^7.1.0: y18n "^3.2.1" yargs-parser "^5.0.1" -yauzl@^2.10.0, yauzl@^2.4.2: +yauzl@^2.10.0: version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== dependencies: buffer-crc32 "~0.2.3" diff --git a/MarkMpn.Sql4Cds.Controls/ExecutionPlanView.cs b/MarkMpn.Sql4Cds.Controls/ExecutionPlanView.cs index b72cecd1..0c9f553b 100644 --- a/MarkMpn.Sql4Cds.Controls/ExecutionPlanView.cs +++ b/MarkMpn.Sql4Cds.Controls/ExecutionPlanView.cs @@ -141,7 +141,14 @@ protected override void OnPaint(PaintEventArgs e) if (iconRect.IntersectsWith(clipRect)) { - using (var stream = GetType().Assembly.GetManifestResourceStream(GetType(), "Images." + kvp.Key.GetType().Name + ".ico")) + var imageName = kvp.Key.GetType().Name; + + if (imageName == "AdaptiveIndexSpoolNode") + imageName = "IndexSpoolNode"; + else if (imageName == "OpenJsonNode" || imageName == "SystemFunctionNode") + imageName = "ExecuteMessageNode"; + + using (var stream = GetType().Assembly.GetManifestResourceStream(GetType(), "Images." + imageName + ".ico")) { Image image; diff --git a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FakeXrmEasyTestsBase.cs b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FakeXrmEasyTestsBase.cs index 1f34ee35..3355415b 100644 --- a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FakeXrmEasyTestsBase.cs +++ b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FakeXrmEasyTestsBase.cs @@ -8,6 +8,7 @@ using FakeXrmEasy.FakeMessageExecutors; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Metadata; namespace MarkMpn.Sql4Cds.Engine.FetchXml.Tests { @@ -23,6 +24,39 @@ public FakeXrmEasyTestsBase() _context.AddFakeMessageExecutor(new WhoAmIHandler()); _service = _context.GetOrganizationService(); + + SetRelationships(_context); + } + + private void SetRelationships(XrmFakedContext context) + { + foreach (var entity in context.CreateMetadataQuery()) + { + if (entity.OneToManyRelationships == null) + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.OneToManyRelationships)).SetValue(entity, Array.Empty()); + + if (entity.ManyToOneRelationships == null) + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ManyToOneRelationships)).SetValue(entity, Array.Empty()); + + if (entity.LogicalName == "account") + { + // Add parentaccountid relationship + var relationship = new OneToManyRelationshipMetadata + { + SchemaName = "account_parentaccount", + ReferencedEntity = "account", + ReferencedAttribute = "accountid", + ReferencingEntity = "account", + ReferencingAttribute = "parentaccountid", + IsHierarchical = true + }; + + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.OneToManyRelationships)).SetValue(entity, entity.OneToManyRelationships.Concat(new[] { relationship }).ToArray()); + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ManyToOneRelationships)).SetValue(entity, entity.ManyToOneRelationships.Concat(new[] { relationship }).ToArray()); + } + + context.SetEntityMetadata(entity); + } } } diff --git a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FetchXml2SqlTests.cs b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FetchXml2SqlTests.cs index 2ff00c19..21cdd4ae 100644 --- a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FetchXml2SqlTests.cs +++ b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/FetchXml2SqlTests.cs @@ -431,9 +431,129 @@ public void ArchiveJoins() Assert.AreEqual("SELECT contact.firstname, contact.lastname, account.name FROM archive.contact INNER JOIN archive.account ON contact.parentcustomerid = account.accountid", NormalizeWhitespace(converted)); } + [TestMethod] + public void Under() + { + var metadata = new AttributeMetadataCache(_service); + var fetch = @" + + + + + + + "; + + var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions { ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations }, out _); + + Assert.AreEqual(NormalizeWhitespace(@" + WITH account_hierarchical(accountid) AS ( + SELECT accountid FROM account WHERE parentaccountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"), NormalizeWhitespace(converted)); + } + + [TestMethod] + public void EqOrUnder() + { + var metadata = new AttributeMetadataCache(_service); + var fetch = @" + + + + + + + "; + + var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions { ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations }, out _); + + Assert.AreEqual(NormalizeWhitespace(@" + WITH account_hierarchical(accountid) AS ( + SELECT accountid FROM account WHERE accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"), NormalizeWhitespace(converted)); + } + + [TestMethod] + public void NotUnder() + { + var metadata = new AttributeMetadataCache(_service); + var fetch = @" + + + + + + + "; + + var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions { ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations }, out _); + + Assert.AreEqual(NormalizeWhitespace(@" + WITH account_hierarchical(accountid) AS ( + SELECT accountid FROM account WHERE accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + ) + SELECT * FROM account WHERE (accountid IS NULL OR accountid NOT IN ( SELECT accountid FROM account_hierarchical ))"), NormalizeWhitespace(converted)); + } + + [TestMethod] + public void Above() + { + var metadata = new AttributeMetadataCache(_service); + var fetch = @" + + + + + + + "; + + var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions { ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations }, out _); + + Assert.AreEqual(NormalizeWhitespace(@" + WITH account_hierarchical(accountid, parentaccountid) AS ( + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account AS anchor ON account.accountid = anchor.parentaccountid WHERE anchor.accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"), NormalizeWhitespace(converted)); + } + + [TestMethod] + public void EqOrAbove() + { + var metadata = new AttributeMetadataCache(_service); + var fetch = @" + + + + + + + "; + + var converted = FetchXml2Sql.Convert(_service, metadata, fetch, new FetchXml2SqlOptions { ConvertFetchXmlOperatorsTo = FetchXmlOperatorConversion.SqlCalculations }, out _); + + Assert.AreEqual(NormalizeWhitespace(@" + WITH account_hierarchical(accountid, parentaccountid) AS ( + SELECT accountid, parentaccountid FROM account WHERE accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"), NormalizeWhitespace(converted)); + } + private static string NormalizeWhitespace(string s) { - return Regex.Replace(s, "\\s+", " "); + return Regex.Replace(s, "\\s+", " ").Trim(); } } } diff --git a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/Metadata/Account.cs b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/Metadata/Account.cs index 0a9856ec..67b245ff 100644 --- a/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/Metadata/Account.cs +++ b/MarkMpn.Sql4Cds.Engine.FetchXml.Tests/Metadata/Account.cs @@ -29,5 +29,12 @@ class Account [AttributeLogicalName("primarycontactid")] [RelationshipSchemaName("account_primarycontact")] public Contact PrimaryContact { get; set; } + + [AttributeLogicalName("parentaccountid")] + public EntityReference ParentAccountId { get; set; } + + [AttributeLogicalName("parentaccountid")] + [RelationshipSchemaName("account_parentaccount")] + public Account ParentAccount { get; set; } } } diff --git a/MarkMpn.Sql4Cds.Engine.NetCore/MarkMpn.Sql4Cds.Engine.NetCore.csproj b/MarkMpn.Sql4Cds.Engine.NetCore/MarkMpn.Sql4Cds.Engine.NetCore.csproj index f8ecc95d..fb4ad13c 100644 --- a/MarkMpn.Sql4Cds.Engine.NetCore/MarkMpn.Sql4Cds.Engine.NetCore.csproj +++ b/MarkMpn.Sql4Cds.Engine.NetCore/MarkMpn.Sql4Cds.Engine.NetCore.csproj @@ -10,10 +10,10 @@ - + - + diff --git a/MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs index bad282d1..1125608b 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs @@ -1324,17 +1324,6 @@ public void StringAgg() } } - [TestMethod] - public void JsonValueNull() - { - using (var con = new Sql4CdsConnection(_localDataSource)) - using (var cmd = con.CreateCommand()) - { - cmd.CommandText = "SELECT JSON_VALUE('{ \"changedAttributes\": [ { \"logicalName\": \"column1\", \"oldValue\": null, \"newValue\": \"\" } ] }', '$.changedAttributes[0].oldValue')"; - Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar()); - } - } - [TestMethod] public void VariantType() { diff --git a/MarkMpn.Sql4Cds.Engine.Tests/CteTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/CteTests.cs new file mode 100644 index 00000000..3d8cee34 --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine.Tests/CteTests.cs @@ -0,0 +1,777 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlTypes; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Remoting.Contexts; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Services.Description; +using System.Xml.Serialization; +using FakeXrmEasy; +using FakeXrmEasy.Extensions; +using MarkMpn.Sql4Cds.Engine.ExecutionPlan; +using Microsoft.SqlServer.TransactSql.ScriptDom; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Metadata; +using Microsoft.Xrm.Sdk.Metadata.Query; +using Microsoft.Xrm.Sdk.Query; +using Microsoft.Xrm.Tooling.Connector; + +namespace MarkMpn.Sql4Cds.Engine.Tests +{ + [TestClass] + public class CteTests : FakeXrmEasyTestsBase, IQueryExecutionOptions + { + private List _supportedJoins = new List + { + JoinOperator.Inner, + JoinOperator.LeftOuter + }; + + CancellationToken IQueryExecutionOptions.CancellationToken => CancellationToken.None; + + bool IQueryExecutionOptions.BlockUpdateWithoutWhere => false; + + bool IQueryExecutionOptions.BlockDeleteWithoutWhere => false; + + bool IQueryExecutionOptions.UseBulkDelete => false; + + int IQueryExecutionOptions.BatchSize => 1; + + bool IQueryExecutionOptions.UseTDSEndpoint => false; + + int IQueryExecutionOptions.MaxDegreeOfParallelism => 10; + + bool IQueryExecutionOptions.ColumnComparisonAvailable => true; + + bool IQueryExecutionOptions.UseLocalTimeZone => true; + + List IQueryExecutionOptions.JoinOperatorsAvailable => _supportedJoins; + + bool IQueryExecutionOptions.BypassCustomPlugins => false; + + void IQueryExecutionOptions.ConfirmInsert(ConfirmDmlStatementEventArgs e) + { + } + + void IQueryExecutionOptions.ConfirmDelete(ConfirmDmlStatementEventArgs e) + { + } + + void IQueryExecutionOptions.ConfirmUpdate(ConfirmDmlStatementEventArgs e) + { + } + + bool IQueryExecutionOptions.ContinueRetrieve(int count) + { + return true; + } + + void IQueryExecutionOptions.Progress(double? progress, string message) + { + } + + string IQueryExecutionOptions.PrimaryDataSource => "local"; + + Guid IQueryExecutionOptions.UserId => Guid.NewGuid(); + + bool IQueryExecutionOptions.QuotedIdentifiers => true; + + public ColumnOrdering ColumnOrdering => ColumnOrdering.Alphabetical; + + [TestMethod] + public void SimpleSelect() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS (SELECT accountid, name FROM account) + SELECT * FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + AssertFetchXml(fetch, @" + + + + + + "); + } + + [TestMethod] + public void ColumnAliases() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte (id, n) AS (SELECT accountid, name FROM account) + SELECT * FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + AssertFetchXml(fetch, @" + + + + + + "); + } + + [TestMethod] + public void MultipleAnchorQueries() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte (id, n) AS (SELECT accountid, name FROM account UNION ALL select contactid, fullname FROM contact) + SELECT * FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var concat = AssertNode(select.Source); + var account = AssertNode(concat.Sources[0]); + AssertFetchXml(account, @" + + + + + + "); + var contact = AssertNode(concat.Sources[1]); + AssertFetchXml(contact, @" + + + + + + "); + } + + [TestMethod] + public void MergeFilters() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS (SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark') + SELECT * FROM cte WHERE lastname = 'Carrington'"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + AssertFetchXml(fetch, @" + + + + + + + + + + + "); + } + + [TestMethod] + public void MultipleReferencesWithAliases() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS (SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark') + SELECT * FROM cte a INNER JOIN cte b ON a.lastname = b.lastname"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + AssertFetchXml(fetch, @" + + + + + + + + + + + + + + + + + + + + "); + } + + [TestMethod] + public void MultipleReferencesInUnionAll() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS (SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark') + SELECT * FROM cte UNION ALL SELECT cte.* FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var concat = AssertNode(select.Source); + var fetch1 = AssertNode(concat.Sources[0]); + var fetch2 = AssertNode(concat.Sources[1]); + Assert.AreNotEqual(fetch1, fetch2); + + foreach (var fetch in new[] { fetch1, fetch2 }) + { + AssertFetchXml(fetch, @" + + + + + + + + + + "); + } + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void MultipleRecursiveReferences() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT cte.* FROM cte a INNER JOIN cte b ON a.lastname = b.lastname + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void HintsOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT cte.* FROM cte WITH (NOLOCK) + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void RecursionWithoutUnionAll() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION + SELECT cte.* FROM cte + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(QueryParseException))] + public void OrderByWithoutTop() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT cte.* FROM cte + ORDER BY firstname + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void GroupByOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT cte.* FROM cte GROUP BY contactid, firstname, lastname + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void AggregateOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT MIN(contactid), MIN(firstname), MIN(lastname) FROM cte + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void TopOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT TOP 10 cte.* FROM cte + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void OuterJoinOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT cte.* FROM contact LEFT OUTER JOIN cte ON contact.lastname = cte.lastname + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void SubqueryOnRecursiveReference() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT contactid, firstname, lastname FROM contact WHERE lastname IN (SELECT lastname FROM cte) + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void IncorrectColumnCount() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte (id, fname) AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + [ExpectedException(typeof(NotSupportedQueryFragmentException))] + public void AnonymousColumn() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname + '', lastname FROM contact WHERE firstname = 'Mark' + ) + SELECT * FROM cte"; + + planBuilder.Build(query, null, out _); + } + + [TestMethod] + public void AliasedAnonymousColumn() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte (id, fname, lname) AS ( + SELECT contactid, firstname + '', lastname FROM contact WHERE firstname = 'Mark' + ) + SELECT * FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + Assert.AreEqual("id", select.ColumnSet[0].OutputColumn); + Assert.AreEqual("contact.contactid", select.ColumnSet[0].SourceColumn); + Assert.AreEqual("fname", select.ColumnSet[1].OutputColumn); + Assert.AreEqual("Expr1", select.ColumnSet[1].SourceColumn); + Assert.AreEqual("lname", select.ColumnSet[2].OutputColumn); + Assert.AreEqual("contact.lastname", select.ColumnSet[2].SourceColumn); + var compute = AssertNode(select.Source); + Assert.AreEqual("firstname + ''", compute.Columns["Expr1"].ToSql()); + var fetch = AssertNode(compute.Source); + AssertFetchXml(fetch, @" + + + + + + + + + + "); + } + + [TestMethod] + public void SimpleRecursion() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH cte AS ( + SELECT contactid, firstname, lastname FROM contact WHERE firstname = 'Mark' + UNION ALL + SELECT c.contactid, c.firstname, c.lastname FROM contact c INNER JOIN cte ON c.parentcustomerid = cte.contactid + ) + SELECT * FROM cte"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + Assert.AreEqual("contactid", select.ColumnSet[0].OutputColumn); + Assert.AreEqual("firstname", select.ColumnSet[1].OutputColumn); + Assert.AreEqual("lastname", select.ColumnSet[2].OutputColumn); + var spoolProducer = AssertNode(select.Source); + var concat = AssertNode(spoolProducer.Source); + var depth0 = AssertNode(concat.Sources[0]); + var anchor = AssertNode(depth0.Source); + + AssertFetchXml(anchor, @" + + + + + + + + + + "); + + var assert = AssertNode(concat.Sources[1]); + var nestedLoop = AssertNode(assert.Source); + var depthPlus1 = AssertNode(nestedLoop.LeftSource); + var spoolConsumer = AssertNode(depthPlus1.Source); + var adaptiveSpool = AssertNode(nestedLoop.RightSource); + var childrenFiltered = AssertNode(adaptiveSpool.UnspooledSource); + var childrenUnfiltered = AssertNode(adaptiveSpool.SpooledSource); + + AssertFetchXml(childrenFiltered, @" + + + + + + + + + + "); + + AssertFetchXml(childrenUnfiltered, @" + + + + + + + + "); + } + + [TestMethod] + public void FactorialCalc() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" + WITH Factorial (N, Factorial) AS ( + SELECT 1, 1 + UNION ALL + SELECT N + 1, (N + 1) * Factorial FROM Factorial WHERE N < 5) + SELECT N, Factorial FROM Factorial"; + + using (var reader = cmd.ExecuteReader()) + { + var n = 1; + var factorial = 1; + + while (n <= 5) + { + Assert.IsTrue(reader.Read()); + Assert.AreEqual(n, reader.GetInt32(0)); + Assert.AreEqual(factorial, reader.GetInt32(1)); + + n++; + factorial *= n; + } + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void FactorialCalcFiltered() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" + WITH Factorial (N, Factorial) AS ( + SELECT 1, 1 + UNION ALL + SELECT N + 1, (N + 1) * Factorial FROM Factorial WHERE N < 5) + SELECT Factorial FROM Factorial WHERE N = 3"; + + Assert.AreEqual(6, cmd.ExecuteScalar()); + } + } + + [TestMethod] + public void FactorialCalcFilteredCaseInsensitive() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" + with factorial (N, Factorial) as ( + select 1, 1 + union all + select N + 1, (N + 1) * factorial from factorial where n < 10 + ) + select factorial from factorial where n = 3"; + + Assert.AreEqual(6, cmd.ExecuteScalar()); + } + } + + [TestMethod] + public void Under() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH account_hierarchical(accountid) AS ( + SELECT accountid FROM account WHERE parentaccountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + + AssertFetchXml(fetch, @" + + + + + + + + "); + } + + [TestMethod] + public void EqOrUnder() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH account_hierarchical(accountid) AS ( + SELECT accountid FROM account WHERE accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + + AssertFetchXml(fetch, @" + + + + + + + + "); + } + + [TestMethod] + public void Above() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH account_hierarchical(accountid, parentaccountid) AS ( + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account AS anchor ON account.accountid = anchor.parentaccountid WHERE anchor.accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + + AssertFetchXml(fetch, @" + + + + + + + + "); + } + + [TestMethod] + public void EqOrAbove() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" + WITH account_hierarchical(accountid, parentaccountid) AS ( + SELECT accountid, parentaccountid FROM account WHERE accountid = 'e2218046-f778-42f6-a8a7-772d0653349b' + UNION ALL + SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid + ) + SELECT * FROM account WHERE accountid IN ( SELECT accountid FROM account_hierarchical )"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var fetch = AssertNode(select.Source); + + AssertFetchXml(fetch, @" + + + + + + + + "); + } + + private T AssertNode(IExecutionPlanNode node) where T : IExecutionPlanNode + { + Assert.IsInstanceOfType(node, typeof(T)); + return (T)node; + } + + private void AssertFetchXml(FetchXmlScan node, string fetchXml) + { + try + { + var serializer = new XmlSerializer(typeof(FetchXml.FetchType)); + using (var reader = new StringReader(fetchXml)) + { + var fetch = (FetchXml.FetchType)serializer.Deserialize(reader); + PropertyEqualityAssert.Equals(fetch, node.FetchXml); + } + } + catch (AssertFailedException ex) + { + Assert.Fail($"Expected:\r\n{fetchXml}\r\n\r\nActual:\r\n{node.FetchXmlString}\r\n\r\n{ex.Message}"); + } + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanNodeTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanNodeTests.cs index 992c5902..3db165ef 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanNodeTests.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanNodeTests.cs @@ -37,7 +37,7 @@ public void ConstantScanTest() Alias = "test" }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(1, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["test.firstname"]).Value); @@ -84,7 +84,7 @@ public void FilterNodeTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(1, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["test.firstname"]).Value); @@ -161,7 +161,7 @@ public void MergeJoinInnerTest() JoinType = QualifiedJoinType.Inner }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(2, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["f.firstname"]).Value); @@ -241,7 +241,7 @@ public void MergeJoinLeftOuterTest() JoinType = QualifiedJoinType.LeftOuter }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(3, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["f.firstname"]).Value); @@ -323,7 +323,7 @@ public void MergeJoinRightOuterTest() JoinType = QualifiedJoinType.RightOuter }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(3, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["f.firstname"]).Value); @@ -362,7 +362,7 @@ public void AssertionTest() ErrorMessage = "Only Mark is allowed" }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).GetEnumerator(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).GetEnumerator(); Assert.IsTrue(results.MoveNext()); Assert.AreEqual("Mark", results.Current.GetAttributeValue("test.name").Value); @@ -420,7 +420,7 @@ public void ComputeScalarTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("mul").Value) .ToArray(); @@ -462,7 +462,7 @@ public void DistinctTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.value1").Value) .ToArray(); @@ -504,7 +504,7 @@ public void DistinctCaseInsensitiveTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.value1").Value) .ToArray(); @@ -562,7 +562,7 @@ public void SortNodeTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.expectedorder").Value) .ToArray(); @@ -627,7 +627,7 @@ public void SortNodePresortedTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.expectedorder").Value) .ToArray(); @@ -659,11 +659,11 @@ public void TableSpoolTest() var spool = new TableSpoolNode { Source = source }; - var results1 = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results1 = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.value1").Value) .ToArray(); - var results2 = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results2 = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => e.GetAttributeValue("test.value1").Value) .ToArray(); @@ -708,7 +708,7 @@ public void CaseInsenstiveHashMatchAggregateNodeTest() } }; - var results = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)) + var results = spool.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)) .Select(e => new { Name = e.GetAttributeValue("src.value1").Value, Count = e.GetAttributeValue("count").Value }) .ToArray(); @@ -749,7 +749,7 @@ public void SqlTransformSingleResult() public void AggregateInitialTest() { var aggregate = CreateAggregateTest(); - var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).Single(); + var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).Single(); Assert.AreEqual(SqlInt32.Null, result["min"]); Assert.AreEqual(SqlInt32.Null, result["max"]); @@ -767,7 +767,7 @@ public void AggregateInitialTest() public void AggregateSingleValueTest() { var aggregate = CreateAggregateTest(1); - var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).Single(); + var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).Single(); Assert.AreEqual((SqlInt32)1, result["min"]); Assert.AreEqual((SqlInt32)1, result["max"]); @@ -785,7 +785,7 @@ public void AggregateSingleValueTest() public void AggregateTwoEqualValuesTest() { var aggregate = CreateAggregateTest(1, 1); - var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).Single(); + var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).Single(); Assert.AreEqual((SqlInt32)1, result["min"]); Assert.AreEqual((SqlInt32)1, result["max"]); @@ -803,7 +803,7 @@ public void AggregateTwoEqualValuesTest() public void AggregateMultipleValuesTest() { var aggregate = CreateAggregateTest(1, 3, 1, 1); - var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).Single(); + var result = aggregate.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).Single(); Assert.AreEqual((SqlInt32)1, result["min"]); Assert.AreEqual((SqlInt32)3, result["max"]); @@ -962,7 +962,7 @@ public void NestedLoopJoinInnerTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(2, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["f.firstname"]).Value); @@ -1034,7 +1034,7 @@ public void NestedLoopJoinLeftOuterTest() } }; - var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null)).ToArray(); + var results = node.Execute(new NodeExecutionContext(_localDataSource, new StubOptions(), null, null, null)).ToArray(); Assert.AreEqual(3, results.Length); Assert.AreEqual("Mark", ((SqlString)results[0]["f.firstname"]).Value); diff --git a/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs index d08dfa6c..5a6a3d24 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs @@ -128,6 +128,8 @@ public void SimpleSelectStar() "ownerid", "owneridname", "owneridtype", + "parentaccountid", + "parentaccountidname", "primarycontactid", "primarycontactidname", "turnover" @@ -1995,7 +1997,7 @@ SELECT TOP 10 var filter = AssertNode(top.Source); var constant = AssertNode(filter.Source); - var schema = constant.GetSchema(new NodeCompilationContext(_dataSources, this, null)); + var schema = constant.GetSchema(new NodeCompilationContext(_dataSources, this, null, null)); Assert.AreEqual(typeof(SqlInt32), schema.Schema["a.ID"].Type.ToNetType(out _)); Assert.AreEqual(typeof(SqlString), schema.Schema["a.name"].Type.ToNetType(out _)); } @@ -3271,7 +3273,7 @@ GROUP BY firstname }, }; - var result = select.Execute(new NodeExecutionContext(_localDataSource, this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var result = select.Execute(new NodeExecutionContext(_localDataSource, this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(result); @@ -3720,7 +3722,7 @@ DECLARE @test int { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -3730,7 +3732,7 @@ DECLARE @test int } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues, null), out _); } } } @@ -3774,7 +3776,7 @@ public void SetVariableInDeclaration() { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -3784,7 +3786,7 @@ public void SetVariableInDeclaration() } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_dataSources, this, parameterTypes, parameterValues, null), out _); } } } @@ -3832,7 +3834,7 @@ DECLARE @test varchar(3) { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -3842,7 +3844,7 @@ DECLARE @test varchar(3) } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), out _); } } } @@ -3866,7 +3868,7 @@ DECLARE @test varchar(3) { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -3876,7 +3878,7 @@ DECLARE @test varchar(3) } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), out _); } } } @@ -3958,7 +3960,7 @@ DECLARE @test varchar(3) { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -3968,7 +3970,7 @@ DECLARE @test varchar(3) } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), out _); } } } @@ -3992,7 +3994,7 @@ DECLARE @test varchar { if (plan is IDataReaderExecutionPlanNode selectQuery) { - var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), CommandBehavior.Default); + var results = selectQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(results); @@ -4002,7 +4004,7 @@ DECLARE @test varchar } else if (plan is IDmlQueryExecutionPlanNode dmlQuery) { - dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues), out _); + dmlQuery.Execute(new NodeExecutionContext(_localDataSource, this, parameterTypes, parameterValues, null), out _); } } } @@ -6424,5 +6426,67 @@ WHERE contactid IN (SELECT DISTINCT primarycontactid FROM account WHERE name = _supportedJoins.Remove(JoinOperator.Any); } } + + [TestMethod] + public void FoldFilterToCorrectTableAlias() + { + // The same table alias can be used in the main query and in a query-derived table. Ensure filters are + // folded to the correct one. + + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @" +SELECT * +FROM (SELECT name FROM account AS a INNER JOIN contact AS c ON a.primarycontactid = c.contactid) AS q +INNER JOIN contact AS c ON q.name = c.fullname +WHERE c.firstname = 'Mark'"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var select = AssertNode(plans[0]); + var join = AssertNode(select.Source); + var leftFetch = AssertNode(join.LeftSource); + var rightFetch = AssertNode(join.RightSource); + + AssertFetchXml(leftFetch, @" + + + + + + + + + "); + + AssertFetchXml(rightFetch, @" + + + + + + + + + + "); + } + + [TestMethod] + public void IgnoreDupKeyHint() + { + var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); + + var query = @"INSERT INTO account (accountid, name) VALUES ('{CD503427-E785-40D8-AD0E-FBDF4918D298}', 'Data8') OPTION (USE HINT ('IGNORE_DUP_KEY'))"; + + var plans = planBuilder.Build(query, null, out _); + + Assert.AreEqual(1, plans.Length); + + var insert = AssertNode(plans[0]); + Assert.IsTrue(insert.IgnoreDuplicateKey); + } } } diff --git a/MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs b/MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs index e02f760e..20155e14 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs @@ -117,6 +117,9 @@ public FakeXrmEasyTestsBase() SetColumnNumber(_context); SetColumnNumber(_context2); + + SetRelationships(_context); + SetRelationships(_context2); } private void SetPrimaryNameAttributes(XrmFakedContext context) @@ -159,6 +162,8 @@ private void SetLookupTargets(XrmFakedContext context) typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ObjectTypeCode)).SetValue(entity, 1); var primaryContactId = (LookupAttributeMetadata)entity.Attributes.Single(a => a.LogicalName == "primarycontactid"); primaryContactId.Targets = new[] { "contact" }; + var parentAccountId = (LookupAttributeMetadata)entity.Attributes.Single(a => a.LogicalName == "parentaccountid"); + parentAccountId.Targets = new[] { "account" }; context.SetEntityMetadata(entity); } @@ -243,5 +248,36 @@ private void SetColumnNumber(XrmFakedContext context) context.SetEntityMetadata(entity); } } + + private void SetRelationships(XrmFakedContext context) + { + foreach (var entity in context.CreateMetadataQuery()) + { + if (entity.OneToManyRelationships == null) + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.OneToManyRelationships)).SetValue(entity, Array.Empty()); + + if (entity.ManyToOneRelationships == null) + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ManyToOneRelationships)).SetValue(entity, Array.Empty()); + + if (entity.LogicalName == "account") + { + // Add parentaccountid relationship + var relationship = new OneToManyRelationshipMetadata + { + SchemaName = "account_parentaccount", + ReferencedEntity = "account", + ReferencedAttribute = "accountid", + ReferencingEntity = "account", + ReferencingAttribute = "parentaccountid", + IsHierarchical = true + }; + + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.OneToManyRelationships)).SetValue(entity, entity.OneToManyRelationships.Concat(new[] { relationship }).ToArray()); + typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ManyToOneRelationships)).SetValue(entity, entity.ManyToOneRelationships.Concat(new[] { relationship }).ToArray()); + } + + context.SetEntityMetadata(entity); + } + } } } diff --git a/MarkMpn.Sql4Cds.Engine.Tests/JsonFunctionTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/JsonFunctionTests.cs new file mode 100644 index 00000000..8ac2dc21 --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine.Tests/JsonFunctionTests.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MarkMpn.Sql4Cds.Engine.ExecutionPlan; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace MarkMpn.Sql4Cds.Engine.Tests +{ + [TestClass] + public class JsonFunctionTests : FakeXrmEasyTestsBase + { + [TestMethod] + [DataRow("lax $", null, false)] + [DataRow("strict $", null, true)] + [DataRow("lax $.info.type", "1", false)] + [DataRow("strict $.info.type", "1", false)] + [DataRow("lax $.info.address.town", "Bristol", false)] + [DataRow("strict $.info.address.town", "Bristol", false)] + [DataRow("lax $.info.\"address\"", null, false)] + [DataRow("strict $.info.\"address\"", null, true)] + [DataRow("lax $.info.tags", null, false)] + [DataRow("strict $.info.tags", null, true)] + [DataRow("lax $.info.type[0]", null, false)] + [DataRow("strict $.info.type[0]", null, true)] + [DataRow("lax $.info.none", null, false)] + [DataRow("strict $.info.none", null, true)] + public void JsonValue(string path, string expectedValue, bool expectedError) + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @jsonInfo NVARCHAR(MAX) + +SET @jsonInfo=N'{ + ""info"":{ + ""type"":1, + ""address"":{ + ""town"":""Bristol"", + ""county"":""Avon"", + ""country"":""England"" + }, + ""tags"":[""Sport"", ""Water polo""] + }, + ""type"":""Basic"" + }' + +SELECT JSON_VALUE(@jsonInfo, @path)"; + + var param = cmd.CreateParameter(); + param.ParameterName = "@path"; + param.Value = path; + cmd.Parameters.Add(param); + + if (expectedError) + { + Assert.ThrowsException(() => cmd.ExecuteScalar()); + } + else + { + if (expectedValue == null) + Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar()); + else + Assert.AreEqual(expectedValue, cmd.ExecuteScalar()); + } + } + } + + [TestMethod] + public void JsonValueNull() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT JSON_VALUE('{ \"changedAttributes\": [ { \"logicalName\": \"column1\", \"oldValue\": null, \"newValue\": \"\" } ] }', '$.changedAttributes[0].oldValue')"; + Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar()); + } + } + + [TestMethod] + [DataRow("lax $", null, true, false)] + [DataRow("strict $", null, true, false)] + [DataRow("lax $.info.type", null, false, false)] + [DataRow("strict $.info.type", null, false, true)] + [DataRow("lax $.info.address.town", null, false, false)] + [DataRow("strict $.info.address.town", null, false, true)] + [DataRow("lax $.info.\"address\"", @"{ + ""town"": ""Cheltenham"", + ""county"": ""Gloucestershire"", + ""country"": ""England"" + }", false, false)] + [DataRow("strict $.info.\"address\"", @"{ + ""town"": ""Cheltenham"", + ""county"": ""Gloucestershire"", + ""country"": ""England"" + }", false, false)] + [DataRow("lax $.info.tags", "[\"Sport\", \"Water polo\"]", false, false)] + [DataRow("strict $.info.tags", "[\"Sport\", \"Water polo\"]", false, false)] + [DataRow("lax $.info.type[0]", null, false, false)] + [DataRow("strict $.info.type[0]", null, false, true)] + [DataRow("lax $.info.none", null, false, false)] + [DataRow("strict $.info.none", null, false, true)] + public void JsonQuery(string path, string expectedValue, bool expectedFullValue, bool expectedError) + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT JSON_QUERY(@json, @path)"; + + var jsonParam = cmd.CreateParameter(); + jsonParam.ParameterName = "@json"; + jsonParam.Value = @"{ + ""info"": { + ""type"": 1, + ""address"": { + ""town"": ""Cheltenham"", + ""county"": ""Gloucestershire"", + ""country"": ""England"" + }, + ""tags"": [""Sport"", ""Water polo""] + }, + ""type"": ""Basic"" +}"; + cmd.Parameters.Add(jsonParam); + + var pathParam = cmd.CreateParameter(); + pathParam.ParameterName = "@path"; + pathParam.Value = path; + cmd.Parameters.Add(pathParam); + + if (expectedFullValue) + expectedValue = (string)jsonParam.Value; + + if (expectedError) + { + Assert.ThrowsException(() => cmd.ExecuteScalar()); + } + else + { + if (expectedValue == null) + Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar()); + else + Assert.AreEqual(expectedValue, cmd.ExecuteScalar()); + } + } + } + + [TestMethod] + public void IsJsonTrue() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT ISJSON('true', VALUE)"; + Assert.AreEqual(true, cmd.ExecuteScalar()); + } + } + + [TestMethod] + public void IsJsonUnquotedString() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT ISJSON('test string', VALUE)"; + Assert.AreEqual(false, cmd.ExecuteScalar()); + } + } + + [TestMethod] + public void IsJsonQuotedString() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = "SELECT ISJSON('\"test string\"', SCALAR)"; + Assert.AreEqual(true, cmd.ExecuteScalar()); + } + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine.Tests/JsonPathTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/JsonPathTests.cs new file mode 100644 index 00000000..cb3610e5 --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine.Tests/JsonPathTests.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace MarkMpn.Sql4Cds.Engine.Tests +{ + [TestClass] + public class JsonPathTests + { + [TestMethod] + public void DollarOnly() + { + var path = new JsonPath("$"); + + var json = JsonDocument.Parse(@" +{ + ""path"": { + ""to"": { + ""sub-object"": ""hello world"" + } + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual(value, json.RootElement); + } + + [TestMethod] + public void QuotedPropertyName() + { + var path = new JsonPath("$.path.to.\"sub-object\""); + + var json = JsonDocument.Parse(@" +{ + ""path"": { + ""to"": { + ""sub-object"": ""hello world"" + } + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual("hello world", value.Value.GetString()); + } + + [TestMethod] + public void DuplicatePathsReturnsFirstMatch() + { + var path = new JsonPath("$.person.name"); + + var json = JsonDocument.Parse(@" +{ + ""person"": { + ""name"": ""Mark"", + ""name"": ""Carrington"" + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual("Mark", value.Value.GetString()); + } + + [TestMethod] + public void DefaultModeLax() + { + var path = new JsonPath("$.path.to.\"sub-object\""); + Assert.AreEqual(JsonPathMode.Lax, path.Mode); + } + + [TestMethod] + public void ExplicitModeLax() + { + var path = new JsonPath("lax $.path.to.\"sub-object\""); + Assert.AreEqual(JsonPathMode.Lax, path.Mode); + } + + [TestMethod] + public void ExplicitModeStrict() + { + var path = new JsonPath("strict $.path.to.\"sub-object\""); + Assert.AreEqual(JsonPathMode.Strict, path.Mode); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnUnknownMode() + { + new JsonPath("laxtrict $.path.to.\"sub-object\""); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnExtraQuotes() + { + new JsonPath("laxtrict $.path.to.\"\"sub-object\"\""); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnMissingLeadingDollar() + { + new JsonPath("path.to.\"sub-object\""); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnDoublePeriod() + { + new JsonPath("$.path..to.\"sub-object\""); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnTrailingPeriod() + { + new JsonPath("$.path.to.\"sub-object\"."); + } + + [TestMethod] + public void ArrayIndexer() + { + var path = new JsonPath("$.path.to.\"sub-object\"[1]"); + + var json = JsonDocument.Parse(@" +{ + ""path"": { + ""to"": { + ""sub-object"": [ ""hello"", ""world"" ] + } + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual("world", value.Value.GetString()); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnNegativeIndexer() + { + new JsonPath("$.path.to.\"sub-object\"[-1]"); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnAlphaIndexer() + { + new JsonPath("$.path.to.\"sub-object\"[x]"); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnMissingCloseBracket() + { + new JsonPath("$.path.to.\"sub-object\"[1"); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnMissingOpeningBracket() + { + new JsonPath("$.path.to1]"); + } + + [TestMethod] + public void NestedArrayIndexer() + { + var path = new JsonPath("$.path.to.\"sub-object\"[1][0]"); + + var json = JsonDocument.Parse(@" +{ + ""path"": { + ""to"": { + ""sub-object"": [ [ ""hel"", ""lo"" ], [ ""wor"", ""ld"" ] ] + } + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual("wor", value.Value.GetString()); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnDollarNotAtStart() + { + new JsonPath("$.path.$.to"); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnUnquotedDollar() + { + new JsonPath("$.path$"); + } + + [TestMethod] + [ExpectedException(typeof(JsonException))] + public void FailsOnLeadingNumber() + { + new JsonPath("$.1path"); + } + + [TestMethod] + public void TrailingNumber() + { + var path = new JsonPath("$.path1.to2.\"sub-object\""); + + var json = JsonDocument.Parse(@" +{ + ""path1"": { + ""to2"": { + ""sub-object"": ""hello world"" + } + } +}"); + + var value = path.Evaluate(json.RootElement); + Assert.AreEqual("hello world", value.Value.GetString()); + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine.Tests/MarkMpn.Sql4Cds.Engine.Tests.csproj b/MarkMpn.Sql4Cds.Engine.Tests/MarkMpn.Sql4Cds.Engine.Tests.csproj index 3a4fa1a8..601079fc 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/MarkMpn.Sql4Cds.Engine.Tests.csproj +++ b/MarkMpn.Sql4Cds.Engine.Tests/MarkMpn.Sql4Cds.Engine.Tests.csproj @@ -78,15 +78,19 @@ + + + + @@ -123,6 +127,12 @@ 3.0.2 + + 6.0.0 + + + 6.0.7 + diff --git a/MarkMpn.Sql4Cds.Engine.Tests/Metadata/Account.cs b/MarkMpn.Sql4Cds.Engine.Tests/Metadata/Account.cs index 291fbcf0..40bae6df 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/Metadata/Account.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/Metadata/Account.cs @@ -48,5 +48,12 @@ class Account [AttributeLogicalName("owneridname")] public string OwnerIdName { get; } + + [AttributeLogicalName("parentaccountid")] + [RelationshipSchemaName("account_parent")] + public Account ParentAccount { get; set; } + + [AttributeLogicalName("parentaccountid")] + public EntityReference ParentAccountId { get; set; } } } diff --git a/MarkMpn.Sql4Cds.Engine.Tests/OpenJsonTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/OpenJsonTests.cs new file mode 100644 index 00000000..99bd3681 --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine.Tests/OpenJsonTests.cs @@ -0,0 +1,506 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace MarkMpn.Sql4Cds.Engine.Tests +{ + [TestClass] + public class OpenJsonTests : FakeXrmEasyTestsBase + { + [TestMethod] + public void OpenJsonDefaultSchema() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @json NVARCHAR(MAX) + +SET @json='{""name"":""John"",""surname"":""Doe"",""age"":45,""skills"":[""SQL"",""C#"",""MVC""]}'; + +SELECT * +FROM OPENJSON(@json);"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("key", reader.GetName(0)); + Assert.AreEqual("value", reader.GetName(1)); + Assert.AreEqual("type", reader.GetName(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("name", reader.GetString(0)); + Assert.AreEqual("John", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("surname", reader.GetString(0)); + Assert.AreEqual("Doe", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("age", reader.GetString(0)); + Assert.AreEqual("45", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("skills", reader.GetString(0)); + Assert.AreEqual("[\"SQL\",\"C#\",\"MVC\"]", reader.GetString(1)); + Assert.AreEqual(4, reader.GetInt32(2)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void OpenJsonDefaultSchemaWithPath() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @json NVARCHAR(4000) = N'{ + ""path"": { + ""to"":{ + ""sub-object"":[""en-GB"", ""en-UK"",""de-AT"",""es-AR"",""sr-Cyrl""] + } + } + }'; + +SELECT [key], value +FROM OPENJSON(@json,'$.path.to.""sub-object""')"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("key", reader.GetName(0)); + Assert.AreEqual("value", reader.GetName(1)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("en-GB", reader.GetString(1)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("en-UK", reader.GetString(1)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("2", reader.GetString(0)); + Assert.AreEqual("de-AT", reader.GetString(1)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("3", reader.GetString(0)); + Assert.AreEqual("es-AR", reader.GetString(1)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("4", reader.GetString(0)); + Assert.AreEqual("sr-Cyrl", reader.GetString(1)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void OpenJsonDefaultSchemaDataTypes() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @json NVARCHAR(2048) = N'{ + ""String_value"": ""John"", + ""DoublePrecisionFloatingPoint_value"": 45, + ""DoublePrecisionFloatingPoint_value"": 2.3456, + ""BooleanTrue_value"": true, + ""BooleanFalse_value"": false, + ""Null_value"": null, + ""Array_value"": [""a"",""r"",""r"",""a"",""y""], + ""Object_value"": {""obj"":""ect""} +}'; + +SELECT * FROM OpenJson(@json);"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("key", reader.GetName(0)); + Assert.AreEqual("value", reader.GetName(1)); + Assert.AreEqual("type", reader.GetName(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("String_value", reader.GetString(0)); + Assert.AreEqual("John", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("DoublePrecisionFloatingPoint_value", reader.GetString(0)); + Assert.AreEqual("45", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("DoublePrecisionFloatingPoint_value", reader.GetString(0)); + Assert.AreEqual("2.3456", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("BooleanTrue_value", reader.GetString(0)); + Assert.AreEqual("true", reader.GetString(1)); + Assert.AreEqual(3, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("BooleanFalse_value", reader.GetString(0)); + Assert.AreEqual("false", reader.GetString(1)); + Assert.AreEqual(3, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("Null_value", reader.GetString(0)); + Assert.IsTrue(reader.IsDBNull(1)); + Assert.AreEqual(0, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("Array_value", reader.GetString(0)); + Assert.AreEqual("[\"a\",\"r\",\"r\",\"a\",\"y\"]", reader.GetString(1)); + Assert.AreEqual(4, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("Object_value", reader.GetString(0)); + Assert.AreEqual("{\"obj\":\"ect\"}", reader.GetString(1)); + Assert.AreEqual(5, reader.GetInt32(2)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void OpenJsonExplicitSchema() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @json NVARCHAR(MAX) = N'[ + { + ""Order"": { + ""Number"":""SO43659"", + ""Date"":""2011-05-31T00:00:00"" + }, + ""AccountNumber"":""AW29825"", + ""Item"": { + ""Price"":2024.9940, + ""Quantity"":1 + } + }, + { + ""Order"": { + ""Number"":""SO43661"", + ""Date"":""2011-06-01T00:00:00"" + }, + ""AccountNumber"":""AW73565"", + ""Item"": { + ""Price"":2024.9940, + ""Quantity"":3 + } + } +]' + +SELECT * +FROM OPENJSON ( @json ) +WITH ( + Number VARCHAR(200) '$.Order.Number', + Date DATETIME '$.Order.Date', + Customer VARCHAR(200) '$.AccountNumber', + Quantity INT '$.Item.Quantity', + [Order] NVARCHAR(MAX) AS JSON + )"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("Number", reader.GetName(0)); + Assert.AreEqual("Date", reader.GetName(1)); + Assert.AreEqual("Customer", reader.GetName(2)); + Assert.AreEqual("Quantity", reader.GetName(3)); + Assert.AreEqual("Order", reader.GetName(4)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("SO43659", reader.GetString(0)); + Assert.AreEqual(new DateTime(2011, 5, 31), reader.GetDateTime(1)); + Assert.AreEqual("AW29825", reader.GetString(2)); + Assert.AreEqual(1, reader.GetInt32(3)); + Assert.AreEqual(@"{ + ""Number"":""SO43659"", + ""Date"":""2011-05-31T00:00:00"" + }", reader.GetString(4)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("SO43661", reader.GetString(0)); + Assert.AreEqual(new DateTime(2011, 6, 1), reader.GetDateTime(1)); + Assert.AreEqual("AW73565", reader.GetString(2)); + Assert.AreEqual(3, reader.GetInt32(3)); + Assert.AreEqual(@"{ + ""Number"":""SO43661"", + ""Date"":""2011-06-01T00:00:00"" + }", reader.GetString(4)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void MergeJson() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @json1 NVARCHAR(MAX),@json2 NVARCHAR(MAX) + +SET @json1=N'{""name"": ""John"", ""surname"":""Doe""}' + +SET @json2=N'{""name"": ""John"", ""age"":45}' + +SELECT * +FROM OPENJSON(@json1) +UNION ALL +SELECT * +FROM OPENJSON(@json2) +WHERE [key] NOT IN (SELECT [key] FROM OPENJSON(@json1))"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("key", reader.GetName(0)); + Assert.AreEqual("value", reader.GetName(1)); + Assert.AreEqual("type", reader.GetName(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("name", reader.GetString(0)); + Assert.AreEqual("John", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("surname", reader.GetString(0)); + Assert.AreEqual("Doe", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("age", reader.GetString(0)); + Assert.AreEqual("45", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void NestedJson() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +--simple cross apply example +DECLARE @JSON NVARCHAR(MAX) = N'[ +{ +""OrderNumber"":""SO43659"", +""OrderDate"":""2011-05-31T00:00:00"", +""AccountNumber"":""AW29825"", +""ItemPrice"":2024.9940, +""ItemQuantity"":1 +}, +{ +""OrderNumber"":""SO43661"", +""OrderDate"":""2011-06-01T00:00:00"", +""AccountNumber"":""AW73565"", +""ItemPrice"":2024.9940, +""ItemQuantity"":3 +} +]' + +SELECT root.[key] AS [Order],TheValues.[key], TheValues.[value] +FROM OPENJSON ( @JSON ) AS root +CROSS APPLY OPENJSON ( root.value) AS TheValues"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("Order", reader.GetName(0)); + Assert.AreEqual("key", reader.GetName(1)); + Assert.AreEqual("value", reader.GetName(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("OrderNumber", reader.GetString(1)); + Assert.AreEqual("SO43659", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("OrderDate", reader.GetString(1)); + Assert.AreEqual("2011-05-31T00:00:00", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("AccountNumber", reader.GetString(1)); + Assert.AreEqual("AW29825", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("ItemPrice", reader.GetString(1)); + Assert.AreEqual("2024.9940", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("0", reader.GetString(0)); + Assert.AreEqual("ItemQuantity", reader.GetString(1)); + Assert.AreEqual("1", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("OrderNumber", reader.GetString(1)); + Assert.AreEqual("SO43661", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("OrderDate", reader.GetString(1)); + Assert.AreEqual("2011-06-01T00:00:00", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("AccountNumber", reader.GetString(1)); + Assert.AreEqual("AW73565", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("ItemPrice", reader.GetString(1)); + Assert.AreEqual("2024.9940", reader.GetString(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("1", reader.GetString(0)); + Assert.AreEqual("ItemQuantity", reader.GetString(1)); + Assert.AreEqual("3", reader.GetString(2)); + + Assert.IsFalse(reader.Read()); + } + } + } + + [TestMethod] + public void RecursiveCTEJson() + { + using (var con = new Sql4CdsConnection(_localDataSource)) + using (var cmd = con.CreateCommand()) + { + cmd.CommandText = @" +DECLARE @JSON NVARCHAR(MAX) = N'[ +{ +""OrderNumber"":""SO43659"", +""OrderDate"":""2011-05-31T00:00:00"", +""AccountNumber"":""AW29825"", +""ItemPrice"":2024.9940, +""ItemQuantity"":1 +}, +{ +""OrderNumber"":""SO43661"", +""OrderDate"":""2011-06-01T00:00:00"", +""AccountNumber"":""AW73565"", +""ItemPrice"":2024.9940, +""ItemQuantity"":3 +} +]'; + + +with cte ([key], value, type) as ( + select '$[' + [key] + ']', value, type from OPENJSON(@json) + + union all + + select cte.[key] + case when cte.type = 4 then '[' + childvalues.[key] + ']' else '.' + childvalues.[key] end, childvalues.value, childvalues.type from cte cross apply OPENJSON(cte.value) as childvalues WHERE cte.type in (4, 5) +) + +SELECT * from CTE"; + + using (var reader = cmd.ExecuteReader()) + { + Assert.AreEqual("key", reader.GetName(0)); + Assert.AreEqual("value", reader.GetName(1)); + Assert.AreEqual("type", reader.GetName(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0]", reader.GetString(0)); + Assert.AreEqual(@"{ +""OrderNumber"":""SO43659"", +""OrderDate"":""2011-05-31T00:00:00"", +""AccountNumber"":""AW29825"", +""ItemPrice"":2024.9940, +""ItemQuantity"":1 +}", reader.GetString(1)); + Assert.AreEqual(5, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1]", reader.GetString(0)); + Assert.AreEqual(@"{ +""OrderNumber"":""SO43661"", +""OrderDate"":""2011-06-01T00:00:00"", +""AccountNumber"":""AW73565"", +""ItemPrice"":2024.9940, +""ItemQuantity"":3 +}", reader.GetString(1)); + Assert.AreEqual(5, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1].OrderNumber", reader.GetString(0)); + Assert.AreEqual("SO43661", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1].OrderDate", reader.GetString(0)); + Assert.AreEqual("2011-06-01T00:00:00", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1].AccountNumber", reader.GetString(0)); + Assert.AreEqual("AW73565", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1].ItemPrice", reader.GetString(0)); + Assert.AreEqual("2024.9940", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[1].ItemQuantity", reader.GetString(0)); + Assert.AreEqual("3", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0].OrderNumber", reader.GetString(0)); + Assert.AreEqual("SO43659", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0].OrderDate", reader.GetString(0)); + Assert.AreEqual("2011-05-31T00:00:00", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0].AccountNumber", reader.GetString(0)); + Assert.AreEqual("AW29825", reader.GetString(1)); + Assert.AreEqual(1, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0].ItemPrice", reader.GetString(0)); + Assert.AreEqual("2024.9940", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("$[0].ItemQuantity", reader.GetString(0)); + Assert.AreEqual("1", reader.GetString(1)); + Assert.AreEqual(2, reader.GetInt32(2)); + + Assert.IsFalse(reader.Read()); + } + } + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine.Tests/Sql2FetchXmlTests.cs b/MarkMpn.Sql4Cds.Engine.Tests/Sql2FetchXmlTests.cs index 001d9bf0..f00071ac 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/Sql2FetchXmlTests.cs +++ b/MarkMpn.Sql4Cds.Engine.Tests/Sql2FetchXmlTests.cs @@ -126,6 +126,8 @@ public void SelectStar() "ownerid", "owneridname", "owneridtype", + "parentaccountid", + "parentaccountidname", "primarycontactid", "primarycontactidname", "turnover" @@ -157,6 +159,8 @@ public void SelectStarAndField() "ownerid", "owneridname", "owneridtype", + "parentaccountid", + "parentaccountidname", "primarycontactid", "primarycontactidname", "turnover", @@ -702,7 +706,7 @@ public void SelectArithmetic() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -750,7 +754,7 @@ public void WhereComparingTwoFields() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -794,7 +798,7 @@ public void WhereComparingExpression() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -835,7 +839,7 @@ public void BackToFrontLikeExpression() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -870,7 +874,7 @@ public void UpdateFieldToField() } }; - ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), out _); + ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), out _); Assert.AreEqual("Carrington", _context.Data["contact"][guid]["firstname"]); } @@ -902,7 +906,7 @@ public void UpdateFieldToExpression() } }; - ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), out _); + ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), out _); Assert.AreEqual("Hello Carrington", _context.Data["contact"][guid]["firstname"]); } @@ -938,7 +942,7 @@ public void UpdateReplace() } }; - ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), out _); + ((UpdateNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), out _); Assert.AreEqual("--CDS--", _context.Data["contact"][guid]["firstname"]); } @@ -969,7 +973,7 @@ public void StringFunctions() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1009,7 +1013,7 @@ public void SelectExpression() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1059,7 +1063,7 @@ public void SelectExpressionNullValues() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1104,7 +1108,7 @@ public void OrderByExpression() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1149,7 +1153,7 @@ public void OrderByAliasedField() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1193,7 +1197,7 @@ public void OrderByCalculatedField() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1237,7 +1241,7 @@ public void OrderByCalculatedFieldByIndex() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1279,7 +1283,7 @@ public void DateCalculations() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1364,7 +1368,7 @@ public void CustomFilterAggregateHavingProjectionSortAndTop() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1427,7 +1431,7 @@ public void FilterCaseInsensitive() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1484,7 +1488,7 @@ public void GroupCaseInsensitive() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1537,7 +1541,7 @@ public void AggregateExpressionsWithoutGrouping() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1592,7 +1596,7 @@ public void AggregateQueryProducesAlternative() } }; - var dataReader = alternativeQuery.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = alternativeQuery.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1646,7 +1650,7 @@ public void GuidEntityReferenceInequality() } }; - var dataReader = select.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = select.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -1697,7 +1701,7 @@ public void UpdateGuidToEntityReference() } }; - update.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), out _); + update.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), out _); Assert.AreEqual(new EntityReference("contact", contact1), _context.Data["account"][account1].GetAttributeValue("primarycontactid")); Assert.AreEqual(new EntityReference("contact", contact2), _context.Data["account"][account2].GetAttributeValue("primarycontactid")); @@ -1971,7 +1975,7 @@ public void ImplicitTypeConversion() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2004,7 +2008,7 @@ public void ImplicitTypeConversionComparison() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2029,7 +2033,7 @@ public void GlobalOptionSet() Assert.AreEqual("name = 'test'", filterNode.Filter.ToSql()); var optionsetNode = (GlobalOptionSetQueryNode)filterNode.Source; - var dataReader = selectNode.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = selectNode.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2051,7 +2055,7 @@ public void EntityDetails() var sortNode = (SortNode)selectNode.Source; var metadataNode = (MetadataQueryNode)sortNode.Source; - var dataReader = selectNode.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = selectNode.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2070,7 +2074,7 @@ public void AttributeDetails() var planBuilder = new ExecutionPlanBuilder(_localDataSource.Values, this); var queries = planBuilder.Build(query, null, out _); - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2126,7 +2130,7 @@ public void OptionSetNameSelect() CollectionAssert.AreEqual(new[] { "new_optionsetvalue", "new_optionsetvaluename" }, select.ColumnSet.Select(c => c.OutputColumn).ToList()); - var dataReader = select.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = select.Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2450,7 +2454,7 @@ public void CharIndex() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2480,7 +2484,7 @@ public void CastDateTimeToDate() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); @@ -2518,7 +2522,7 @@ public void GroupByPrimaryFunction() } }; - var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary()), CommandBehavior.Default); + var dataReader = ((SelectNode)queries[0]).Execute(new NodeExecutionContext(GetDataSources(_context), this, new Dictionary(), new Dictionary(), null), CommandBehavior.Default); var dataTable = new DataTable(); dataTable.Load(dataReader); diff --git a/MarkMpn.Sql4Cds.Engine.Tests/app.config b/MarkMpn.Sql4Cds.Engine.Tests/app.config index 1de11e40..8a0f6cf2 100644 --- a/MarkMpn.Sql4Cds.Engine.Tests/app.config +++ b/MarkMpn.Sql4Cds.Engine.Tests/app.config @@ -16,7 +16,7 @@ - + diff --git a/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsCommand.cs b/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsCommand.cs index d3fc7dc8..e04571c7 100644 --- a/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsCommand.cs +++ b/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsCommand.cs @@ -42,6 +42,7 @@ public Sql4CdsCommand(Sql4CdsConnection connection, string commandText) DbParameterCollection = new Sql4CdsParameterCollection(); _planBuilder = new ExecutionPlanBuilder(_connection.DataSources.Values, _connection.Options); + _planBuilder.Log = msg => _connection.OnInfoMessage(null, msg); } /// @@ -116,6 +117,7 @@ protected override DbConnection DbConnection _connection = con; _planBuilder = new ExecutionPlanBuilder(_connection.DataSources.Values, _connection.Options); + _planBuilder.Log = msg => _connection.OnInfoMessage(null, msg); Plan = null; UseTDSEndpointDirectly = false; } diff --git a/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsDataReader.cs b/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsDataReader.cs index c5b5bc47..1155a8eb 100644 --- a/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsDataReader.cs +++ b/MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsDataReader.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Linq.Expressions; using System.Text; +using System.Xml; using MarkMpn.Sql4Cds.Engine.ExecutionPlan; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.Xrm.Sdk; @@ -62,13 +63,15 @@ public Sql4CdsDataReader(Sql4CdsCommand command, IQueryExecutionOptions options, private bool Execute(Dictionary parameterTypes, Dictionary parameterValues) { - var context = new NodeExecutionContext(_connection.DataSources, _options, parameterTypes, parameterValues); + IRootExecutionPlanNode logNode = null; + var context = new NodeExecutionContext(_connection.DataSources, _options, parameterTypes, parameterValues, msg => _connection.OnInfoMessage(logNode, msg)); try { while (_instructionPointer < _command.Plan.Length && !_options.CancellationToken.IsCancellationRequested) { var node = _command.Plan[_instructionPointer]; + logNode = node; if (node is IDataReaderExecutionPlanNode dataSetNode) { @@ -90,10 +93,7 @@ private bool Execute(Dictionary parameterTypes, Dicti else if (node is IDmlQueryExecutionPlanNode dmlNode) { dmlNode = (IDmlQueryExecutionPlanNode)dmlNode.Clone(); - var msg = dmlNode.Execute(context, out var recordsAffected); - - if (!String.IsNullOrEmpty(msg)) - _connection.OnInfoMessage(dmlNode, msg); + dmlNode.Execute(context, out var recordsAffected); _command.OnStatementCompleted(dmlNode, recordsAffected); diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AdaptiveIndexSpoolNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AdaptiveIndexSpoolNode.cs new file mode 100644 index 00000000..df2689ba --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AdaptiveIndexSpoolNode.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; +using Microsoft.SqlServer.TransactSql.ScriptDom; +using Microsoft.Xrm.Sdk; + +namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan +{ + class AdaptiveIndexSpoolNode : BaseDataNode + { + private IndexSpoolNode _indexSpool; + + public AdaptiveIndexSpoolNode() + { + _indexSpool = new IndexSpoolNode(); + } + + [Browsable(false)] + public IDataExecutionPlanNodeInternal SpooledSource + { + get => _indexSpool.Source; + set => _indexSpool.Source = value; + } + + [Browsable(false)] + public IDataExecutionPlanNodeInternal UnspooledSource { get; set; } + + /// + /// The column in the data source to create an index on + /// + [Category("Index Spool")] + [DisplayName("Key Column")] + [Description("The column in the data source to create an index on")] + public string KeyColumn + { + get => _indexSpool.KeyColumn; + set => _indexSpool.KeyColumn = value; + } + + /// + /// The name of the parameter to use for seeking in the index + /// + [Category("Index Spool")] + [DisplayName("Seek Value")] + [Description("The name of the parameter to use for seeking in the index")] + public string SeekValue + { + get => _indexSpool.SeekValue; + set => _indexSpool.SeekValue = value; + } + + public override void AddRequiredColumns(NodeCompilationContext context, IList requiredColumns) + { + UnspooledSource.AddRequiredColumns(context, requiredColumns); + _indexSpool.AddRequiredColumns(context, requiredColumns); + } + + public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext context, IList hints) + { + _indexSpool.FoldQuery(context, hints); + UnspooledSource = UnspooledSource.FoldQuery(context, hints); + return this; + } + + public override INodeSchema GetSchema(NodeCompilationContext context) + { + return UnspooledSource.GetSchema(context); + } + + public override IEnumerable GetSources() + { + return new[] { UnspooledSource, SpooledSource }; + } + + protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationContext context) + { + return _indexSpool.EstimateRowsOut(context); + } + + protected override IEnumerable ExecuteInternal(NodeExecutionContext context) + { + IDataExecutionPlanNodeInternal source; + + if (ExecutionCount < 10) + source = UnspooledSource; + else + source = _indexSpool; + + foreach (var result in source.Execute(context)) + yield return result; + } + + public override string ToString() + { + return "Index Spool\r\n(Adaptive)"; + } + + public override object Clone() + { + return new AdaptiveIndexSpoolNode + { + _indexSpool = (IndexSpoolNode)_indexSpool.Clone(), + UnspooledSource = (IDataExecutionPlanNodeInternal)UnspooledSource.Clone(), + KeyColumn = KeyColumn, + SeekValue = SeekValue + }; + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs index 1e4256f1..b3262711 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs @@ -165,6 +165,7 @@ internal void FoldToFetchXML(FetchXmlScan fetchXml) // Add the mappings to the FetchXML to produce the columns with the expected names, and hide all other possible columns var originalAlias = fetchXml.Alias.EscapeIdentifier(); fetchXml.Alias = Alias; + fetchXml.ColumnMappings.Clear(); var escapedAlias = Alias.EscapeIdentifier(); @@ -192,7 +193,7 @@ public override INodeSchema GetSchema(NodeCompilationContext context) // Map the base names to the alias names var sourceSchema = Source.GetSchema(context); var schema = new ColumnList(); - var aliases = new Dictionary>(); + var aliases = new Dictionary>(StringComparer.OrdinalIgnoreCase); var primaryKey = (string)null; var mappings = new Dictionary(StringComparer.OrdinalIgnoreCase); var escapedAlias = Alias.EscapeIdentifier(); @@ -300,7 +301,17 @@ public override object Clone() }; clone.Source.Parent = clone; - clone.ColumnSet.AddRange(ColumnSet); + + foreach (var col in ColumnSet) + { + clone.ColumnSet.Add(new SelectColumn + { + AllColumns = col.AllColumns, + OutputColumn = col.OutputColumn, + SourceColumn = col.SourceColumn, + SourceExpression = col.SourceExpression, + }); + } return clone; } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssertNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssertNode.cs index 9125ce29..980bdf2b 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssertNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssertNode.cs @@ -14,6 +14,11 @@ namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan /// class AssertNode : BaseDataNode, ISingleSourceExecutionPlanNode { + public AssertNode() + { + ExceptionConstructor = msg => new ApplicationException(msg); + } + /// /// The data source for the assertion /// @@ -34,12 +39,18 @@ class AssertNode : BaseDataNode, ISingleSourceExecutionPlanNode [DisplayName("Error Message")] public string ErrorMessage { get; set; } + /// + /// The type of exception to throw when the returns false + /// + [Browsable(false)] + public Func ExceptionConstructor { get; set; } + protected override IEnumerable ExecuteInternal(NodeExecutionContext context) { foreach (var entity in Source.Execute(context)) { if (!Assertion(entity)) - throw new ApplicationException(ErrorMessage); + throw ExceptionConstructor(ErrorMessage); yield return entity; } @@ -78,7 +89,8 @@ public override object Clone() { Source = (IDataExecutionPlanNodeInternal)Source.Clone(), Assertion = Assertion, - ErrorMessage = ErrorMessage + ErrorMessage = ErrorMessage, + ExceptionConstructor = ExceptionConstructor }; clone.Source.Parent = clone; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssignVariablesNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssignVariablesNode.cs index 9aea2a30..3b726b9d 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssignVariablesNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssignVariablesNode.cs @@ -40,7 +40,7 @@ class AssignVariablesNode : BaseDmlNode [Browsable(false)] public override bool ContinueOnError { get; set; } - public override string Execute(NodeExecutionContext context, out int recordsAffected) + public override void Execute(NodeExecutionContext context, out int recordsAffected) { _executionCount++; @@ -63,7 +63,6 @@ public override string Execute(NodeExecutionContext context, out int recordsAffe } recordsAffected = -1; - return null; } /// diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseAggregateNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseAggregateNode.cs index bc1a930d..89f190a9 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseAggregateNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseAggregateNode.cs @@ -387,7 +387,11 @@ protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationConte if (GroupBy.Count == 0) return RowCountEstimateDefiniteRange.ExactlyOne; - var rows = Source.EstimateRowsOut(context).Value * 4 / 10; + var sourceRows = Source.EstimateRowsOut(context).Value; + var rows = sourceRows * 4 / 10; + + if (rows < 0) + rows = sourceRows / 10 * 4; return new RowCountEstimate(rows); } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs index 7b87b638..dfa22b96 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs @@ -190,14 +190,15 @@ public void MergeStatsFrom(BaseDataNode other) /// The SQL criteria to attempt to translate to FetchXML /// The schema of the node that the criteria apply to /// The prefix of the table that the can be translated for, or null if any tables can be referenced + /// The prefixes of any tables that the cannot be translated for /// The logical name of the root entity that the FetchXML query is targetting /// The alias of the root entity that the FetchXML query is targetting /// The child items of the root entity in the FetchXML query /// The FetchXML version of the that is generated by this method /// true if the can be translated to FetchXML, or false otherwise - protected bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttributeMetadataCache metadata, BooleanExpression criteria, INodeSchema schema, string allowedPrefix, string targetEntityName, string targetEntityAlias, object[] items, out filter filter) + protected bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttributeMetadataCache metadata, BooleanExpression criteria, INodeSchema schema, string allowedPrefix, HashSet barredPrefixes, string targetEntityName, string targetEntityAlias, object[] items, out filter filter) { - if (!TranslateFetchXMLCriteria(context, metadata, criteria, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out var condition, out filter)) + if (!TranslateFetchXMLCriteria(context, metadata, criteria, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out var condition, out filter)) return false; if (condition != null) @@ -214,22 +215,23 @@ protected bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttrib /// The SQL criteria to attempt to translate to FetchXML /// The schema of the node that the criteria apply to /// The prefix of the table that the can be translated for, or null if any tables can be referenced + /// The prefixes of any tables that the cannot be translated for /// The logical name of the root entity that the FetchXML query is targetting /// The alias of the root entity that the FetchXML query is targetting /// The child items of the root entity in the FetchXML query /// The FetchXML version of the that is generated by this method when it covers multiple conditions /// The FetchXML version of the that is generated by this method when it is for a single condition only /// true if the can be translated to FetchXML, or false otherwise - private bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttributeMetadataCache metadata, BooleanExpression criteria, INodeSchema schema, string allowedPrefix, string targetEntityName, string targetEntityAlias, object[] items, out condition condition, out filter filter) + private bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttributeMetadataCache metadata, BooleanExpression criteria, INodeSchema schema, string allowedPrefix, HashSet barredPrefixes, string targetEntityName, string targetEntityAlias, object[] items, out condition condition, out filter filter) { condition = null; filter = null; if (criteria is BooleanBinaryExpression binary) { - if (!TranslateFetchXMLCriteria(context, metadata, binary.FirstExpression, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out var lhsCondition, out var lhsFilter)) + if (!TranslateFetchXMLCriteria(context, metadata, binary.FirstExpression, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out var lhsCondition, out var lhsFilter)) return false; - if (!TranslateFetchXMLCriteria(context, metadata, binary.SecondExpression, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out var rhsCondition, out var rhsFilter)) + if (!TranslateFetchXMLCriteria(context, metadata, binary.SecondExpression, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out var rhsCondition, out var rhsFilter)) return false; filter = new filter @@ -246,7 +248,7 @@ private bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttribut if (criteria is BooleanParenthesisExpression paren) { - return TranslateFetchXMLCriteria(context, metadata, paren.Expression, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out condition, out filter); + return TranslateFetchXMLCriteria(context, metadata, paren.Expression, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out condition, out filter); } if (criteria is DistinctPredicate distinct) @@ -469,6 +471,9 @@ private bool TranslateFetchXMLCriteria(NodeCompilationContext context, IAttribut if (allowedPrefix != null && !allowedPrefix.Equals(entityAlias)) return false; + if (barredPrefixes != null && barredPrefixes.Contains(entityAlias)) + return false; + var entityName = AliasToEntityName(targetEntityAlias, targetEntityName, items, entityAlias); if (IsInvalidAuditFilter(targetEntityName, entityName, items)) diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDmlNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDmlNode.cs index 152d211b..c5880b01 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDmlNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDmlNode.cs @@ -129,8 +129,7 @@ public void Dispose() /// /// The context in which the node is being executed /// The number of records that were affected by the query - /// A log message to display - public abstract string Execute(NodeExecutionContext context, out int recordsAffected); + public abstract void Execute(NodeExecutionContext context, out int recordsAffected); /// /// Indicates if some errors returned by the server can be silently ignored @@ -440,10 +439,22 @@ protected Dictionary> CompileColumnMappings(DataSou { var sourceTargetColumnName = mappings[destAttributeName + "type"]; var sourceTargetType = schema.Schema[sourceTargetColumnName].Type; - var stringType = DataTypeHelpers.NVarChar(MetadataExtensions.EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit); + targetExpr = Expression.Property(entityParam, typeof(Entity).GetCustomAttribute().MemberName, Expression.Constant(sourceTargetColumnName)); - targetExpr = SqlTypeConverter.Convert(targetExpr, sourceTargetType, stringType); - targetExpr = SqlTypeConverter.Convert(targetExpr, typeof(string)); + targetExpr = Expression.Convert(targetExpr, sourceTargetType.ToNetType(out _)); + + if (targetExpr.Type == typeof(SqlInt32)) + { + // Using TDS Endpoint, ___type fields are returned as ObjectTypeCode values, not logical names + targetExpr = Expr.Call(() => ObjectTypeCodeToLogicalName(Expr.Arg(), Expr.Arg()), targetExpr, Expression.Constant(dataSource.Metadata)); + } + else + { + // Normally we want to specify the target type as a logical name + var stringType = DataTypeHelpers.NVarChar(MetadataExtensions.EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit); + targetExpr = SqlTypeConverter.Convert(targetExpr, sourceTargetType, stringType); + targetExpr = SqlTypeConverter.Convert(targetExpr, typeof(string)); + } } convertedExpr = SqlTypeConverter.Convert(expr, sourceSqlType, DataTypeHelpers.UniqueIdentifier); @@ -509,6 +520,14 @@ protected Dictionary> CompileColumnMappings(DataSou return attributeAccessors; } + private static string ObjectTypeCodeToLogicalName(SqlInt32 otc, IAttributeMetadataCache attributeMetadataCache) + { + if (otc.IsNull) + throw new QueryExecutionException("Cannot convert null ObjectTypeCode to EntityReference"); + + return attributeMetadataCache[otc.Value].LogicalName; + } + /// /// Provides values to include in log messages /// @@ -539,11 +558,13 @@ protected class OperationNames /// The metadata of the entity that will be affected /// A function to generate a DML request from a data source entity /// The constant strings to use in log messages - /// The final log message - protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptions options, List entities, EntityMetadata meta, Func requestGenerator, OperationNames operationNames, out int recordsAffected, IDictionary parameterValues, Action responseHandler = null) + /// A callback function to be executed when a log message is generated + protected void ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptions options, List entities, EntityMetadata meta, Func requestGenerator, OperationNames operationNames, NodeExecutionContext context, out int recordsAffected, Action responseHandler = null) { var inProgressCount = 0; var count = 0; + var errorCount = 0; + var threadCount = 0; #if NETCOREAPP var svc = dataSource.Connection as ServiceClient; @@ -580,6 +601,7 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio if (!useAffinityCookie && service is CrmServiceClient crmService) crmService.EnableAffinityCookie = false; #endif + Interlocked.Increment(ref threadCount); return new { Service = service, EMR = default(ExecuteMultipleRequest) }; }, @@ -600,7 +622,11 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio { var newCount = Interlocked.Increment(ref inProgressCount); var progress = (double)newCount / entities.Count; - options.Progress(progress, $"{operationNames.InProgressUppercase} {newCount:N0} of {entities.Count:N0} {GetDisplayName(0, meta)} ({progress:P0})..."); + + if (threadCount < 2) + options.Progress(progress, $"{operationNames.InProgressUppercase} {newCount:N0} of {entities.Count:N0} {GetDisplayName(0, meta)} ({progress:P0})..."); + else + options.Progress(progress, $"{operationNames.InProgressUppercase} {newCount - threadCount + 1:N0}-{newCount:N0} of {entities.Count:N0} {GetDisplayName(0, meta)} ({progress:P0}, {threadCount:N0} threads)..."); try { @@ -611,13 +637,15 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio } catch (FaultException ex) { - if (FilterErrors(ex.Detail)) + if (FilterErrors(context, request, ex.Detail)) { if (ContinueOnError) fault = fault ?? ex.Detail; else throw; } + + Interlocked.Increment(ref errorCount); } } else @@ -643,7 +671,7 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio if (threadLocalState.EMR.Requests.Count == BatchSize) { - ProcessBatch(threadLocalState.EMR, ref count, ref inProgressCount, entities, operationNames, meta, options, dataSource, threadLocalState.Service, responseHandler, ref fault); + ProcessBatch(threadLocalState.EMR, threadCount, ref count, ref inProgressCount, ref errorCount, entities, operationNames, meta, options, dataSource, threadLocalState.Service, context, responseHandler, ref fault); threadLocalState = new { threadLocalState.Service, EMR = default(ExecuteMultipleRequest) }; } @@ -654,7 +682,9 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio (threadLocalState) => { if (threadLocalState.EMR != null) - ProcessBatch(threadLocalState.EMR, ref count, ref inProgressCount, entities, operationNames, meta, options, dataSource, threadLocalState.Service, responseHandler, ref fault); + ProcessBatch(threadLocalState.EMR, threadCount, ref count, ref inProgressCount, ref errorCount, entities, operationNames, meta, options, dataSource, threadLocalState.Service, context, responseHandler, ref fault); + + Interlocked.Decrement(ref threadCount); if (threadLocalState.Service != dataSource.Connection && threadLocalState.Service is IDisposable disposableClient) disposableClient.Dispose(); @@ -683,8 +713,8 @@ protected string ExecuteDmlOperation(DataSource dataSource, IQueryExecutionOptio } recordsAffected = count; - parameterValues["@@ROWCOUNT"] = (SqlInt32)count; - return $"{count:N0} {GetDisplayName(count, meta)} {operationNames.CompletedLowercase}"; + context.ParameterValues["@@ROWCOUNT"] = (SqlInt32)count; + context.Log($"{count:N0} {GetDisplayName(count, meta)} {operationNames.CompletedLowercase}"); } protected class BulkApiErrorDetail @@ -694,11 +724,12 @@ protected class BulkApiErrorDetail public int StatusCode { get; set; } } - private void ProcessBatch(ExecuteMultipleRequest req, ref int count, ref int inProgressCount, List entities, OperationNames operationNames, EntityMetadata meta, IQueryExecutionOptions options, DataSource dataSource, IOrganizationService org, Action responseHandler, ref OrganizationServiceFault fault) + private void ProcessBatch(ExecuteMultipleRequest req, int threadCount, ref int count, ref int inProgressCount, ref int errorCount, List entities, OperationNames operationNames, EntityMetadata meta, IQueryExecutionOptions options, DataSource dataSource, IOrganizationService org, NodeExecutionContext context, Action responseHandler, ref OrganizationServiceFault fault) { var newCount = Interlocked.Add(ref inProgressCount, req.Requests.Count); var progress = (double)newCount / entities.Count; - options.Progress(progress, $"{operationNames.InProgressUppercase} {GetDisplayName(0, meta)} {newCount + 1 - req.Requests.Count:N0} - {newCount:N0} of {entities.Count:N0}..."); + var threadCountMessage = threadCount < 2 ? "" : $" ({threadCount:N0} threads)"; + options.Progress(progress, $"{operationNames.InProgressUppercase} {GetDisplayName(0, meta)} {count + errorCount + 1:N0} - {newCount:N0} of {entities.Count:N0}{threadCountMessage}..."); var resp = ExecuteMultiple(dataSource, org, meta, req); if (responseHandler != null) @@ -715,8 +746,9 @@ private void ProcessBatch(ExecuteMultipleRequest req, ref int count, ref int inP .ToList(); Interlocked.Add(ref count, req.Requests.Count - errorResponses.Count); + Interlocked.Add(ref errorCount, errorResponses.Count); - var error = errorResponses.FirstOrDefault(item => FilterErrors(item.Fault)); + var error = errorResponses.FirstOrDefault(item => FilterErrors(context, req.Requests[item.RequestIndex], item.Fault)); if (error != null) { @@ -727,7 +759,7 @@ private void ProcessBatch(ExecuteMultipleRequest req, ref int count, ref int inP } } - protected virtual bool FilterErrors(OrganizationServiceFault fault) + protected virtual bool FilterErrors(NodeExecutionContext context, OrganizationRequest request, OrganizationServiceFault fault) { return true; } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseJoinNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseJoinNode.cs index 2a9afed2..5c85ec19 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseJoinNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseJoinNode.cs @@ -112,6 +112,18 @@ protected Entity Merge(Entity leftEntity, INodeSchema leftSchema, Entity rightEn return merged; } + protected void FoldDefinedValues(INodeSchema rightSchema) + { + foreach (var kvp in DefinedValues.ToList()) + { + if (!rightSchema.ContainsColumn(kvp.Value, out var innerColumn)) + throw new NotSupportedQueryFragmentException($"Unknown defined column '{kvp.Value}'"); + + if (innerColumn != kvp.Value) + DefinedValues[kvp.Key] = innerColumn; + } + } + public override IEnumerable GetSources() { yield return LeftSource; @@ -172,7 +184,10 @@ protected virtual INodeSchema GetSchema(NodeCompilationContext context, bool inc } foreach (var definedValue in DefinedValues) - schema[definedValue.Key] = innerSchema.Schema[definedValue.Value]; + { + innerSchema.ContainsColumn(definedValue.Value, out var innerColumn); + schema[definedValue.Key] = innerSchema.Schema[innerColumn]; + } _lastLeftSchema = outerSchema; _lastRightSchema = innerSchema; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BulkDeleteJobNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BulkDeleteJobNode.cs index 0e10cf80..a46a6917 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BulkDeleteJobNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/BulkDeleteJobNode.cs @@ -43,7 +43,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList(), @@ -73,7 +73,7 @@ public string Execute(NodeExecutionContext context, out int recordsAffected) recordsAffected = 1; context.ParameterValues["@@IDENTITY"] = new SqlEntityReference(DataSource, "asyncoperation", resp.JobId); - return $"Bulk delete job started"; + context.Log("Bulk delete job started"); } } catch (QueryExecutionException ex) diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConcatenateNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConcatenateNode.cs index 8bac4e4f..05f0762a 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConcatenateNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConcatenateNode.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Query; namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan { diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeclareVariablesNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeclareVariablesNode.cs index b0519ba0..6ecb9f34 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeclareVariablesNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeclareVariablesNode.cs @@ -43,7 +43,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList hints) diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeleteNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeleteNode.cs index 17980768..9c30c85b 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeleteNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/DeleteNode.cs @@ -106,7 +106,7 @@ protected override void RenameSourceColumns(IDictionary columnRe SecondaryIdSource = secondaryIdSourceRenamed; } - public override string Execute(NodeExecutionContext context, out int recordsAffected) + public override void Execute(NodeExecutionContext context, out int recordsAffected) { _executionCount++; @@ -172,7 +172,7 @@ public override string Execute(NodeExecutionContext context, out int recordsAffe using (_timer.Run()) { - return ExecuteDmlOperation( + ExecuteDmlOperation( dataSource, context.Options, entities, @@ -184,8 +184,8 @@ public override string Execute(NodeExecutionContext context, out int recordsAffe InProgressLowercase = "deleting", CompletedLowercase = "deleted" }, - out recordsAffected, - context.ParameterValues); + context, + out recordsAffected); } } catch (QueryExecutionException ex) @@ -250,7 +250,7 @@ private OrganizationRequest CreateDeleteRequest(EntityMetadata meta, Entity enti return req; } - protected override bool FilterErrors(OrganizationServiceFault fault) + protected override bool FilterErrors(NodeExecutionContext context, OrganizationRequest request, OrganizationServiceFault fault) { // Ignore errors trying to delete records that don't exist - record may have been deleted by another // process in parallel. diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExecuteAsNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExecuteAsNode.cs index 9eebea94..0c99b53c 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExecuteAsNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExecuteAsNode.cs @@ -51,7 +51,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList hints) @@ -704,5 +704,10 @@ IRootExecutionPlanNodeInternal[] IRootExecutionPlanNodeInternal.FoldQuery(NodeCo FoldQuery(context, hints); return new[] { this }; } + + public override string ToString() + { + return $"Table Valued Function\r\n[{MessageName}]"; + } } } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs index 7998ff50..69d5ec90 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExpressionExtensions.cs @@ -5,19 +5,12 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Xml; -using System.Xml.XPath; using MarkMpn.Sql4Cds.Engine.Visitors; -using Microsoft.Crm.Sdk.Messages; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.Xrm.Sdk; -using Newtonsoft.Json.Linq; using Wmhelp.XPath2; -using Wmhelp.XPath2.Extensions; namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan { @@ -640,47 +633,59 @@ private static MethodInfo GetMethod(FunctionCall func, ExpressionCompilationCont { KeyValuePair[] paramExpressionsWithType; - // Special case for DATEPART / DATEDIFF / DATEADD - first parameter looks like a field but is actually an identifier - if (func.FunctionName.Value.Equals("DATEPART", StringComparison.OrdinalIgnoreCase) || - func.FunctionName.Value.Equals("DATEDIFF", StringComparison.OrdinalIgnoreCase) || - func.FunctionName.Value.Equals("DATEADD", StringComparison.OrdinalIgnoreCase)) - { - paramExpressionsWithType = func.Parameters - .Select((param, index) => + paramExpressionsWithType = func.Parameters + .Select((param, index) => + { + // Special case for DATEPART / DATEDIFF / DATEADD - first parameter looks like a field but is actually an identifier + if (index == 0 && + ( + func.FunctionName.Value.Equals("DATEPART", StringComparison.OrdinalIgnoreCase) || + func.FunctionName.Value.Equals("DATEDIFF", StringComparison.OrdinalIgnoreCase) || + func.FunctionName.Value.Equals("DATEADD", StringComparison.OrdinalIgnoreCase) + )) { - if (index == 0) + // Check parameter is an expected datepart value + if (!(param is ColumnReferenceExpression col) || col.MultiPartIdentifier.Identifiers.Count != 1) + throw new NotSupportedQueryFragmentException("Expected a datepart name", param); + + try + { + ExpressionFunctions.DatePartToInterval(col.MultiPartIdentifier.Identifiers.Single().Value); + } + catch { - // Check parameter is an expected datepart value - if (!(param is ColumnReferenceExpression col)) - throw new NotSupportedQueryFragmentException("Expected a datepart name", param); - - try - { - ExpressionFunctions.DatePartToInterval(col.MultiPartIdentifier.Identifiers.Single().Value); - } - catch - { - throw new NotSupportedQueryFragmentException("Expected a datepart name", param); - } - - return new KeyValuePair(Expression.Constant(col.MultiPartIdentifier.Identifiers.Single().Value), DataTypeHelpers.NVarChar(col.MultiPartIdentifier.Identifiers.Single().Value.Length, context.PrimaryDataSource.DefaultCollation, CollationLabel.CoercibleDefault)); + throw new NotSupportedQueryFragmentException("Expected a datepart name", param); } - var paramExpr = param.ToExpression(context, contextParam, out var paramType); - return new KeyValuePair(paramExpr, paramType); - }) - .ToArray(); - } - else - { - paramExpressionsWithType = func.Parameters - .Select(param => + return new KeyValuePair(Expression.Constant(col.MultiPartIdentifier.Identifiers.Single().Value), DataTypeHelpers.NVarChar(col.MultiPartIdentifier.Identifiers.Single().Value.Length, context.PrimaryDataSource.DefaultCollation, CollationLabel.CoercibleDefault)); + } + + // Special case for ISJSON - second optional parameter looks like a field but is actually a JSON data type + if (index == 1 && func.FunctionName.Value.Equals("ISJSON", StringComparison.OrdinalIgnoreCase)) { - var paramExpr = param.ToExpression(context, contextParam, out var paramType); - return new KeyValuePair(paramExpr, paramType); - }) - .ToArray(); - } + // Check parameter is an expected datepart value + if (!(param is ColumnReferenceExpression col) || col.MultiPartIdentifier.Identifiers.Count != 1) + throw new NotSupportedQueryFragmentException("Expected a JSON type", param); + + switch (col.MultiPartIdentifier.Identifiers.Single().Value.ToLowerInvariant()) + { + case "value": + case "array": + case "object": + case "scalar": + break; + + default: + throw new NotSupportedQueryFragmentException("Expected a JSON type", param); + } + + return new KeyValuePair(Expression.Constant(col.MultiPartIdentifier.Identifiers.Single().Value), DataTypeHelpers.NVarChar(col.MultiPartIdentifier.Identifiers.Single().Value.Length, context.PrimaryDataSource.DefaultCollation, CollationLabel.CoercibleDefault)); + } + + var paramExpr = param.ToExpression(context, contextParam, out var paramType); + return new KeyValuePair(paramExpr, paramType); + }) + .ToArray(); if (func.CallTarget != null) { @@ -1821,7 +1826,7 @@ public static string EscapeIdentifier(this string identifier) /// /// https://learn.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver16&redirectedfrom=MSDN#rules-for-regular-identifiers /// - private static bool IsValidIdentifier(string identifier) + public static bool IsValidIdentifier(this string identifier) { if (String.IsNullOrEmpty(identifier)) return false; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs index ebc85a30..59c69c25 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs @@ -1185,7 +1185,7 @@ private void AddSchemaAttribute(DataSource dataSource, ColumnList schema, Dictio if (attrMetadata is LookupAttributeMetadata lookup) { - AddSchemaAttribute(schema, aliases, fullName + "name", attrMetadata.LogicalName + "name", DataTypeHelpers.NVarChar(lookup.Targets == null || lookup.Targets.Length == 0 ? 100 : lookup.Targets.Select(e => ((StringAttributeMetadata)dataSource.Metadata[e].Attributes.SingleOrDefault(a => a.LogicalName == dataSource.Metadata[e].PrimaryNameAttribute))?.MaxLength ?? 100).Max(), dataSource.DefaultCollation, CollationLabel.Implicit), notNull); + AddSchemaAttribute(schema, aliases, fullName + "name", attrMetadata.LogicalName + "name", DataTypeHelpers.NVarChar(lookup.Targets == null || lookup.Targets.Length == 0 ? 100 : lookup.Targets.Select(e => (dataSource.Metadata[e].Attributes.SingleOrDefault(a => a.LogicalName == dataSource.Metadata[e].PrimaryNameAttribute) as StringAttributeMetadata)?.MaxLength ?? 100).Max(), dataSource.DefaultCollation, CollationLabel.Implicit), notNull); if (lookup.Targets?.Length != 1 && lookup.AttributeType != AttributeTypeCode.PartyList) AddSchemaAttribute(schema, aliases, fullName + "type", attrMetadata.LogicalName + "type", DataTypeHelpers.NVarChar(MetadataExtensions.EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit), notNull); @@ -1249,14 +1249,15 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext if (FoldFilterToIndexSpool(context, out var indexSpool)) { + NormalizeFilters(); Parent = indexSpool; - return indexSpool; + return indexSpool.FoldQuery(context, hints); } return this; } - private bool FoldFilterToIndexSpool(NodeCompilationContext context, out IndexSpoolNode indexSpool) + private bool FoldFilterToIndexSpool(NodeCompilationContext context, out IDataExecutionPlanNodeInternal indexSpool) { if (Entity.Items == null) { @@ -1288,11 +1289,11 @@ private bool FoldFilterToIndexSpool(NodeCompilationContext context, out IndexSpo { var loop = parent as NestedLoopNode; - if (loop != null && prev == loop.RightSource) + if (loop != null && prev == loop.RightSource && loop.OuterReferences.Any(kvp => kvp.Value.Equals(variableCondition.value, StringComparison.OrdinalIgnoreCase))) { var rowCount = loop.LeftSource.EstimateRowsOut(context); - if (rowCount.Value >= 100 && loop.OuterReferences.Any(kvp => kvp.Value.Equals(variableCondition.value, StringComparison.OrdinalIgnoreCase))) + if (rowCount.Value >= 100) { indexSpool = new IndexSpoolNode { @@ -1301,6 +1302,27 @@ private bool FoldFilterToIndexSpool(NodeCompilationContext context, out IndexSpo SeekValue = variableCondition.value }; + foreach (var filter in Entity.Items.OfType()) + filter.Items = filter.Items.Except(new[] { variableCondition }).ToArray(); + + return true; + } + else if (loop.LeftSource is ComputeScalarNode leftComputeScalar && + leftComputeScalar.Source is TableSpoolNode leftSpool && + leftSpool.Producer != null) + { + // In the recursive part of a CTE. We might only be being called for one record at a time, but that might happen + // lots of times. Add an adaptive spool in to avoid excessive calls + var clone = (FetchXmlScan)Clone(); + + indexSpool = new AdaptiveIndexSpoolNode + { + UnspooledSource = clone, + SpooledSource = this, + KeyColumn = (variableCondition.entityname ?? Alias) + "." + variableCondition.attribute, + SeekValue = variableCondition.value + }; + foreach (var filter in Entity.Items.OfType()) filter.Items = filter.Items.Except(new[] { variableCondition }).ToArray(); @@ -1682,14 +1704,18 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList map.OutputColumn == normalizedCol); + var mapping = ColumnMappings.SingleOrDefault(map => map.OutputColumn == normalizedCol || map.OutputColumn == parts[0] && map.AllColumns); - if (mapping != null) + if (mapping != null && mapping.AllColumns) + normalizedCol = (mapping.SourceColumn ?? parts[0]).EscapeIdentifier() + "." + parts[1].EscapeIdentifier(); + else if (mapping != null) normalizedCol = mapping.SourceColumn; + else if (HiddenAliases.Contains(parts[0], StringComparer.OrdinalIgnoreCase)) + continue; var attr = AddAttribute(normalizedCol, null, dataSource.Metadata, out _, out var linkEntity); - if (mapping != null && attr != null) + if (mapping != null && !mapping.AllColumns && attr != null) { if (attr.name != parts[1] && IsValidAlias(parts[1])) attr.alias = parts[1]; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FilterNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FilterNode.cs index 7b11aefd..2737a2e9 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FilterNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FilterNode.cs @@ -27,6 +27,14 @@ class FilterNode : BaseDataNode, ISingleSourceExecutionPlanNode [Description("The filter to apply")] public BooleanExpression Filter { get; set; } + /// + /// Indicates if the filter should be evaluated during startup only + /// + [Category("Filter")] + [DisplayName("Startup Expression")] + [Description("Indicates if the filter shold be evaluated during startup only")] + public bool StartupExpression { get; set; } + /// /// The data source to select from /// @@ -40,6 +48,9 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont var filter = Filter.Compile(expressionCompilationContext); var expressionContext = new ExpressionExecutionContext(context); + if (StartupExpression && !filter(expressionContext)) + yield break; + foreach (var entity in Source.Execute(context)) { expressionContext.Entity = entity; @@ -164,9 +175,21 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext if (FoldScalarSubqueries(context, out var nestedLoop)) return nestedLoop.FoldQuery(context, hints); + // Check if we can apply the filter during startup instead of per-record + StartupExpression = CheckStartupExpression(); + return this; } + private bool CheckStartupExpression() + { + // We only need to apply the filter expression to individual rows if it references any fields + if (Filter.GetColumns().Any()) + return false; + + return true; + } + private BooleanExpression FoldNotIsNullToIsNotNull(BooleanExpression filter) { var visitor = new RefactorNotIsNullVisitor(filter); @@ -893,6 +916,11 @@ private bool FoldInExistsToFetchXml(NodeCompilationContext context, IList l.linktype == "inner")) + break; + // Replace the filter on the defined value name with a filter on the primary key column nullFilter.Expression = (rightFetch.Alias + "." + context.DataSources[rightFetch.DataSource].Metadata[rightFetch.Entity.name].PrimaryIdAttribute).ToColumnReference(); @@ -1089,6 +1117,10 @@ private bool FoldFiltersToDataSources(NodeCompilationContext context, IList (ScalarExpression)(escapedAlias + "." + col.OutputColumn).ToColumnReference(), col => col.SourceColumn)) }; - alias.Source = aliasFilterNode.FoldQuery(context, hints); + alias.Source = aliasFilterNode; foldedFilters = true; } @@ -1192,6 +1224,64 @@ private bool FoldFiltersToDataSources(NodeCompilationContext context, IList> GetIgnoreAliasesByNode() + { + var fetchXmlSources = GetFoldableSources(Source) + .OfType() + .ToList(); + + // Build a full list of where we see each alias + var nodesByAlias = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + foreach (var fetchXml in fetchXmlSources) + { + foreach (var alias in GetAliases(fetchXml)) + { + if (!nodesByAlias.TryGetValue(alias, out var nodes)) + { + nodes = new List(); + nodesByAlias.Add(alias, nodes); + } + + nodes.Add(fetchXml); + } + } + + var ignoreAliases = fetchXmlSources + .ToDictionary(f => f, f => new HashSet(StringComparer.OrdinalIgnoreCase)); + + // Aliases should be ignored if they appear as visible in another node, or they are hidden in all nodes + foreach (var alias in nodesByAlias) + { + if (alias.Value.Count < 2) + continue; + + var hiddenNodes = alias.Value + .Where(n => n.HiddenAliases.Contains(alias.Key, StringComparer.OrdinalIgnoreCase)) + .ToList(); + + var visibleNodes = alias.Value + .Except(hiddenNodes) + .ToList(); + + foreach (var node in alias.Value) + { + if (visibleNodes.Count == 0 || visibleNodes.Any(n => n != node)) + ignoreAliases[node].Add(alias.Key); + } + } + + return ignoreAliases; + } + + private IEnumerable GetAliases(FetchXmlScan fetchXml) + { + yield return fetchXml.Alias; + + foreach (var linkEntity in fetchXml.Entity.GetLinkEntities()) + yield return linkEntity.alias; + } + private BooleanExpression ReplaceColumnNames(BooleanExpression filter, Dictionary replacements) { filter = filter.Clone(); @@ -1350,9 +1440,9 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList barredPrefixes, string targetEntityName, string targetEntityAlias, object[] items, out filter filter) { - if (TranslateFetchXMLCriteria(context, metadata, criteria, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out filter)) + if (TranslateFetchXMLCriteria(context, metadata, criteria, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out filter)) return null; if (!(criteria is BooleanBinaryExpression bin)) @@ -1361,8 +1451,8 @@ private BooleanExpression ExtractFetchXMLFilters(NodeCompilationContext context, if (bin.BinaryExpressionType != BooleanBinaryExpressionType.And) return criteria; - bin.FirstExpression = ExtractFetchXMLFilters(context, metadata, bin.FirstExpression, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out var lhsFilter); - bin.SecondExpression = ExtractFetchXMLFilters(context, metadata, bin.SecondExpression, schema, allowedPrefix, targetEntityName, targetEntityAlias, items, out var rhsFilter); + bin.FirstExpression = ExtractFetchXMLFilters(context, metadata, bin.FirstExpression, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out var lhsFilter); + bin.SecondExpression = ExtractFetchXMLFilters(context, metadata, bin.SecondExpression, schema, allowedPrefix, barredPrefixes, targetEntityName, targetEntityAlias, items, out var rhsFilter); filter = (lhsFilter != null && rhsFilter != null) ? new filter { Items = new object[] { lhsFilter, rhsFilter } } : lhsFilter ?? rhsFilter; @@ -1444,7 +1534,7 @@ protected bool TranslateMetadataCriteria(NodeCompilationContext context, Boolean relationshipFilter = null; var expressionCompilationContext = new ExpressionCompilationContext(context, null, null); - var expressionExecutionContext = new ExpressionExecutionContext(new NodeExecutionContext(context.DataSources, context.Options, context.ParameterTypes, null)); + var expressionExecutionContext = new ExpressionExecutionContext(new NodeExecutionContext(context.DataSources, context.Options, context.ParameterTypes, null, null)); if (criteria is BooleanBinaryExpression binary) { @@ -1769,6 +1859,7 @@ public override object Clone() var clone = new FilterNode { Filter = Filter, + StartupExpression = StartupExpression, Source = (IDataExecutionPlanNodeInternal)Source.Clone() }; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FoldableJoinNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FoldableJoinNode.cs index 00620632..11a3894b 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FoldableJoinNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/FoldableJoinNode.cs @@ -56,11 +56,14 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext RightSource = RightSource.FoldQuery(context, hints); RightSource.Parent = this; + var leftSchema = LeftSource.GetSchema(context); + var rightSchema = RightSource.GetSchema(context); + + FoldDefinedValues(rightSchema); + if (SemiJoin) return this; - var leftSchema = LeftSource.GetSchema(context); - var rightSchema = RightSource.GetSchema(context); var leftFilter = JoinType == QualifiedJoinType.Inner || JoinType == QualifiedJoinType.LeftOuter ? LeftSource as FilterNode : null; var rightFilter = JoinType == QualifiedJoinType.Inner || JoinType == QualifiedJoinType.RightOuter ? RightSource as FilterNode : null; var leftFetch = (leftFilter?.Source ?? LeftSource) as FetchXmlScan; @@ -371,7 +374,7 @@ private bool FoldFetchXmlJoin(NodeCompilationContext context, IList leftSchema.ContainsColumn(col, out _)) + .Distinct() .ToList(); var rightColumns = requiredColumns .Where(col => rightSchema.ContainsColumn(col, out _)) + .Concat(DefinedValues.Values) + .Distinct() .ToList(); if (LeftAttribute != null) diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/HashMatchAggregateNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/HashMatchAggregateNode.cs index e9caab2f..f1fe0f28 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/HashMatchAggregateNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/HashMatchAggregateNode.cs @@ -21,6 +21,13 @@ namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan /// class HashMatchAggregateNode : BaseAggregateNode { + class MultiCurrencyAggregateException : ApplicationException + { + public MultiCurrencyAggregateException(string message) : base(message) + { + } + } + private bool _folded; protected override IEnumerable ExecuteInternal(NodeExecutionContext context) @@ -124,6 +131,7 @@ Source is FetchXmlScan fetch && // Check if all the aggregates & groupings can be done in FetchXML. Can only convert them if they can ALL // be handled - if any one needs to be calculated manually, we need to calculate them all. var canUseFetchXmlAggregate = true; + var addMultiCurrencyCheck = false; // Also track if we can partition the query for larger source data sets. We can't partition DISTINCT aggregates, // and need to transform AVG(field) to SUM(field) / COUNT(field) @@ -467,6 +475,10 @@ Source is FetchXmlScan fetch && if ((attr is LookupAttributeMetadata || attr is UniqueIdentifierAttributeMetadata || attr?.IsPrimaryId == true) && (aggregateType == FetchXml.AggregateType.min || aggregateType == FetchXml.AggregateType.max)) canUseFetchXmlAggregate = false; + // Can't do do aggregation on money values in multi-currency orgs + if (attr is MoneyAttributeMetadata money && money.IsBaseCurrency == false) + addMultiCurrencyCheck = true; + var attribute = fetchXml.AddAttribute(colName, a => a.aggregate == aggregateType && a.alias == agg.Key && a.distinct == distinct, metadata, out _, out _); if (attribute.name != attr?.LogicalName) @@ -497,6 +509,57 @@ Source is FetchXmlScan fetch && IDataExecutionPlanNodeInternal firstTry = fetchXml; + if (addMultiCurrencyCheck) + { + var currencyCheckFetchXml = new FetchXmlScan + { + DataSource = fetchXml.DataSource, + Alias = context.GetExpressionName(), + FetchXml = new FetchXml.FetchType + { + top = "2", + Items = new object[] + { + new FetchEntityType + { + name = "transactioncurrency", + Items = new object[] + { + new FetchAttributeType + { + name = "transactioncurrencyid" + } + } + } + } + } + }; + var currencyCount = new StreamAggregateNode + { + Source = currencyCheckFetchXml, + Aggregates = + { + [context.GetExpressionName()] = new Aggregate + { + AggregateType = AggregateType.CountStar + } + } + }; + var singleCurrencyAssert = new AssertNode + { + Source = currencyCount, + Assertion = e => ((SqlInt32)e[currencyCount.Aggregates.Single().Key]).Value == 1, + ErrorMessage = "Multiple currencies found - aggregating non-base currency values is not supported in FetchXML", + ExceptionConstructor = msg => new MultiCurrencyAggregateException(msg) + }; + firstTry = new NestedLoopNode + { + LeftSource = singleCurrencyAssert, + RightSource = firstTry, + JoinType = QualifiedJoinType.Inner + }; + } + // If the main aggregate query fails due to having over 50K records, check if we can retry with partitioning. We // need a createdon field to be available for this to work. if (canPartition) @@ -630,7 +693,7 @@ Source is FetchXmlScan fetch && { TrySource = firstTry, CatchSource = nonFetchXmlAggregate, - ExceptionFilter = ex => (ex is QueryExecutionException qee && (qee.InnerException is PartitionedAggregateNode.PartitionOverflowException || qee.InnerException is FetchXmlScan.InvalidPagingException)) || (GetOrganizationServiceFault(ex, out var fault) && (IsAggregateQueryRetryable(fault) || IsCompositeAddressPluginBug(fault))) + ExceptionFilter = ex => (ex is QueryExecutionException qee && (qee.InnerException is PartitionedAggregateNode.PartitionOverflowException || qee.InnerException is FetchXmlScan.InvalidPagingException || qee.InnerException is MultiCurrencyAggregateException)) || (GetOrganizationServiceFault(ex, out var fault) && (IsAggregateQueryRetryable(fault) || IsCompositeAddressPluginBug(fault))) }; firstTry.Parent = tryCatch; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IDmlQueryExecutionPlanNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IDmlQueryExecutionPlanNode.cs index d865ab29..8e254b73 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IDmlQueryExecutionPlanNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IDmlQueryExecutionPlanNode.cs @@ -18,7 +18,6 @@ internal interface IDmlQueryExecutionPlanNode : IRootExecutionPlanNodeInternal /// /// The context in which the node is being executed /// The number of records that were affected by the query - /// A status message for the results of the query - string Execute(NodeExecutionContext context, out int recordsAffected); + void Execute(NodeExecutionContext context, out int recordsAffected); } } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ISpoolProducerNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ISpoolProducerNode.cs new file mode 100644 index 00000000..b18ba77d --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/ISpoolProducerNode.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xrm.Sdk; + +namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan +{ + /// + /// Provides an interface for nodes that spool data internally + /// + interface ISpoolProducerNode : IDataExecutionPlanNodeInternal + { + /// + /// Accesses the spooled data + /// + /// The sequence of data that has been spooled + IEnumerable GetWorkTable(); + + /// + /// Returns the last cloned version of this node + /// + ISpoolProducerNode LastClone { get; } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs index 9180bf67..90e6a8f0 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs @@ -5,21 +5,22 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using MarkMpn.Sql4Cds.Engine.FetchXml; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Metadata; namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan { /// /// Stores data in a hashtable for fast lookups /// - class IndexSpoolNode : BaseDataNode, ISingleSourceExecutionPlanNode + class IndexSpoolNode : BaseDataNode, ISingleSourceExecutionPlanNode, ISpoolProducerNode { private IDictionary> _hashTable; private Func _keySelector; private Func _seekSelector; - - public IndexSpoolNode() { } + private Stack _stack; [Browsable(false)] public IDataExecutionPlanNodeInternal Source { get; set; } @@ -28,21 +29,33 @@ public IndexSpoolNode() { } /// The column in the data source to create an index on /// [Category("Index Spool")] - [Description("The column in the data source to create an index on")] [DisplayName("Key Column")] + [Description("The column in the data source to create an index on")] public string KeyColumn { get; set; } /// /// The name of the parameter to use for seeking in the index /// [Category("Index Spool")] - [Description("The name of the parameter to use for seeking in the index")] [DisplayName("Seek Value")] + [Description("The name of the parameter to use for seeking in the index")] public string SeekValue { get; set; } + /// + /// Stores the records in a stack to support recursive CTEs + /// + [Category("Index Spool")] + [DisplayName("With Stack")] + [Description("Stores the records in a stack to support recursive CTEs")] + public bool WithStack { get; set; } + + [Browsable(false)] + public ISpoolProducerNode LastClone { get; private set; } + public override void AddRequiredColumns(NodeCompilationContext context, IList requiredColumns) { - requiredColumns.Add(KeyColumn); + if (KeyColumn != null) + requiredColumns.Add(KeyColumn); Source.AddRequiredColumns(context, requiredColumns); } @@ -51,6 +64,9 @@ protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationConte { var rows = Source.EstimateRowsOut(context); + if (KeyColumn == null) + return rows; + if (rows is RowCountEstimateDefiniteRange range && range.Maximum == 1) return range; @@ -61,19 +77,300 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext { Source = Source.FoldQuery(context, hints); - // Index and seek values must be the same type - var indexType = Source.GetSchema(context).Schema[KeyColumn].Type; - var seekType = context.ParameterTypes[SeekValue]; + if (KeyColumn != null && SeekValue != null) + { + // Index and seek values must be the same type + var indexType = Source.GetSchema(context).Schema[KeyColumn].Type; + var seekType = context.ParameterTypes[SeekValue]; - if (!SqlTypeConverter.CanMakeConsistentTypes(indexType, seekType, context.PrimaryDataSource, out var consistentType)) - throw new QueryExecutionException($"No type conversion available for {indexType.ToSql()} and {seekType.ToSql()}"); + if (!SqlTypeConverter.CanMakeConsistentTypes(indexType, seekType, context.PrimaryDataSource, out var consistentType)) + throw new QueryExecutionException($"No type conversion available for {indexType.ToSql()} and {seekType.ToSql()}"); - _keySelector = SqlTypeConverter.GetConversion(indexType, consistentType); - _seekSelector = SqlTypeConverter.GetConversion(seekType, consistentType); + _keySelector = SqlTypeConverter.GetConversion(indexType, consistentType); + _seekSelector = SqlTypeConverter.GetConversion(seekType, consistentType); + } + + if (WithStack) + return FoldCTEToFetchXml(context, hints); return this; } + private IDataExecutionPlanNodeInternal FoldCTEToFetchXml(NodeCompilationContext context, IList hints) + { + // We can use above/below FetchXML conditions for common CTE patterns + // https://learn.microsoft.com/en-us/power-apps/developer/data-platform/query-hierarchical-data + // This always uses the default max recursion depth of 100, so don't use it if we have any other hint + var maxRecursion = hints + .OfType() + .Where(hint => hint.HintKind == OptimizerHintKind.MaxRecursion) + .FirstOrDefault() + ?.Value + ?.Value + ?? "100"; + + if (maxRecursion != "100") + return this; + + // Check we have the required execution plan pattern: + // + // Index Spool ━━ Concatenate ━━ Compute Scalar ━━ FetchXML Query + // ┕ Assert ━━ Nested Loop ━━ Compute Scalar ━━ Table Spool + // ┕ Index Spool ━━ FetchXML Query + // ┕ FetchXML Query + + var concat = Source as ConcatenateNode; + if (concat == null || concat.Sources.Count != 2) + return this; + + var initialDepthCompute = concat.Sources[0] as ComputeScalarNode; + if (initialDepthCompute == null) + return this; + + var anchorFetchXml = initialDepthCompute.Source as FetchXmlScan; + if (anchorFetchXml == null) + return this; + + var depthAssert = concat.Sources[1] as AssertNode; + if (depthAssert == null) + return this; + + var recurseLoop = depthAssert.Source as NestedLoopNode; + if (recurseLoop == null) + return this; + + var incrementDepthCompute = recurseLoop.LeftSource as ComputeScalarNode; + if (incrementDepthCompute == null) + return this; + + var recurseSpoolConsumer = incrementDepthCompute.Source as TableSpoolNode; + if (recurseSpoolConsumer == null || recurseSpoolConsumer.Source != null) + return this; + + var adaptiveSpool = recurseLoop.RightSource as AdaptiveIndexSpoolNode; + if (adaptiveSpool == null) + return this; + + var unspooledRecursiveFetchXml = adaptiveSpool.UnspooledSource as FetchXmlScan; + if (unspooledRecursiveFetchXml == null) + return this; + + var spooledRecursiveFetchXml = adaptiveSpool.SpooledSource as FetchXmlScan; + if (spooledRecursiveFetchXml == null) + return this; + + // We can only use the hierarchical FetchXML filters if the recursion is within the same entity and is using only the + // hierarchical relationship for filtering + if (anchorFetchXml.DataSource != spooledRecursiveFetchXml.DataSource || + anchorFetchXml.Entity.name != spooledRecursiveFetchXml.Entity.name) + return this; + + // Check for any other filters or link-entities + if (spooledRecursiveFetchXml.Entity.GetLinkEntities().Any() || + spooledRecursiveFetchXml.Entity.Items != null && spooledRecursiveFetchXml.Entity.Items.OfType().Any()) + return this; + + // Check there are no extra calculated columns + if (initialDepthCompute.Columns.Count != 1 || incrementDepthCompute.Columns.Count != 1) + return this; + + // Check all columns are consistent + var depthField = initialDepthCompute.Columns.Single().Key; + + for (var i = 0; i < concat.ColumnSet.Count; i++) + { + if (concat.ColumnSet[i].SourceColumns[0] == depthField) + continue; + + var anchorAttribute = concat.ColumnSet[i].SourceColumns[0]; + var recurseAttribute = concat.ColumnSet[i].SourceColumns[1]; + recurseAttribute = recurseLoop.DefinedValues[recurseAttribute]; + + // Ignore any differences in the aliases used for the anchor and recursive parts + anchorAttribute = anchorAttribute.ToColumnReference().MultiPartIdentifier.Identifiers.Last().Value; + recurseAttribute = recurseAttribute.ToColumnReference().MultiPartIdentifier.Identifiers.Last().Value; + + if (anchorAttribute != recurseAttribute) + return this; + } + + var metadata = context.DataSources[anchorFetchXml.DataSource].Metadata[anchorFetchXml.Entity.name]; + var hierarchicalRelationship = metadata.OneToManyRelationships.SingleOrDefault(r => r.IsHierarchical == true); + + if (hierarchicalRelationship == null || + hierarchicalRelationship.ReferencingEntity != hierarchicalRelationship.ReferencedEntity) + return this; + + var anchorKey = adaptiveSpool.SeekValue; // Will be the variable name defined by the recursion loop + anchorKey = recurseLoop.OuterReferences.Single(kvp => kvp.Value == anchorKey).Key; // Will now be the column name defined by the concatenate node + anchorKey = concat.ColumnSet.Single(col => col.OutputColumn == anchorKey).SourceColumns[0]; // Will now be the column from the anchor FetchXML + var anchorCol = anchorKey.ToColumnReference(); + var anchorIsUnder = false; + var anchorIsAbove = false; + FetchLinkEntityType anchorLink = null; + + // The anchor query will normally have the target table as the root entity, but could be a related entity if + // we want to use the "above" condition instead of "eq-or-above" + if (anchorCol.MultiPartIdentifier.Count != 2 || + anchorCol.MultiPartIdentifier.Identifiers[0].Value != anchorFetchXml.Alias) + { + anchorLink = anchorFetchXml.Entity.Items + .OfType() + .Where(link => link.alias == anchorCol.MultiPartIdentifier.Identifiers[0].Value) + .SingleOrDefault(); + + if (anchorLink == null) + return this; + + if (anchorLink.name != anchorFetchXml.Entity.name) + return this; + + if (anchorLink.from == hierarchicalRelationship.ReferencedAttribute && + anchorLink.to == hierarchicalRelationship.ReferencingAttribute) + { + anchorIsAbove = true; + } + else + { + return this; + } + } + + var anchorAttr = anchorCol.MultiPartIdentifier[1].Value; + + var recurseCol = adaptiveSpool.KeyColumn.ToColumnReference(); + if (recurseCol.MultiPartIdentifier.Count != 2 || + recurseCol.MultiPartIdentifier.Identifiers[0].Value != spooledRecursiveFetchXml.Alias) + return this; + var recurseAttr = recurseCol.MultiPartIdentifier[1].Value; + + var isUnder = anchorAttr == hierarchicalRelationship.ReferencedAttribute && recurseAttr == hierarchicalRelationship.ReferencingAttribute; + var isAbove = anchorAttr == hierarchicalRelationship.ReferencingAttribute && recurseAttr == hierarchicalRelationship.ReferencedAttribute; + + if (!isUnder && !isAbove) + return this; + + // The depth counter is no longer generated or used, so remove it from the concat column list + var depthFieldConcatColumn = concat.ColumnSet.Single(c => c.SourceColumns[0] == depthField); + concat.ColumnSet.Remove(depthFieldConcatColumn); + + // We can replace the whole CTE with a single eq-or-above or eq-or-under FetchXML if the anchor + // query filters on a single primary key + var at = GetPrimaryKeyFilter(anchorFetchXml, metadata); + + // Also check for a filter on the hierarchy lookup attribute to convert to "under". + if (at == null && isUnder) + { + at = GetForeignKeyFilter(anchorFetchXml, hierarchicalRelationship); + + if (at != null) + anchorIsUnder = true; + } + + if (at != null) + { + at.@operator = isUnder ? @operator.eqorunder : @operator.eqorabove; + + if (at.@operator == @operator.eqorabove && anchorIsAbove) + { + // If we're using a link entity in the anchor query to find only records above the target record, + // not at-or-above, we can remove the link now. We'll have been using that link for the output values, + // so switch the alias of the top-level entity too + anchorFetchXml.Entity.Items = anchorFetchXml.Entity.Items.Except(new[] { anchorLink }).ToArray(); + at.@operator = @operator.above; + anchorFetchXml.Alias = anchorLink.alias; + } + else if (at.@operator == @operator.eqorunder && anchorIsUnder) + { + // If we're using a filter on the foreign key to represent an "under" condition, switch the filter to + // be on the primary key attribute instead. + at.@operator = @operator.under; + at.attribute = metadata.PrimaryIdAttribute; + } + + // We might have some column renamings applied, so update them too + var alias = Parent as AliasNode; + + if (alias == null) + { + foreach (var col in concat.ColumnSet) + anchorFetchXml.ColumnMappings.Add(new SelectColumn { SourceColumn = col.SourceColumns[0], OutputColumn = col.OutputColumn }); + } + else + { + foreach (var col in alias.ColumnSet) + { + var concatCol = concat.ColumnSet.Single(c => c.OutputColumn == col.SourceColumn); + col.SourceColumn = concatCol.SourceColumns[0]; + } + } + + return anchorFetchXml; + } + + // We can replace the recursive part with a nested loop calling an above or under FetchXML if the anchor + // query is a more complex filter. We don't want to recurse into the results of this second FetchXML though as the recursion + // has already happened server-side, so the execution plan should become: + // + // Concatenate ━━ Index Spool ━━ FetchXML Query + // ┕ Nested Loop ━━ Table Spool + // ┕ FetchXML Query + + var recurseCondition = (condition) unspooledRecursiveFetchXml.Entity.Items.OfType().Single().Items.Single(); + recurseCondition.attribute = metadata.PrimaryIdAttribute; + recurseCondition.@operator = isUnder ? @operator.under : @operator.above; + + concat.Sources[0] = this; + Parent = concat; + Source = anchorFetchXml; + anchorFetchXml.Parent = this; + concat.Sources[1] = recurseLoop; + recurseLoop.Parent = concat; + recurseLoop.LeftSource = recurseSpoolConsumer; + recurseSpoolConsumer.Parent = recurseLoop; + recurseLoop.RightSource = unspooledRecursiveFetchXml; + unspooledRecursiveFetchXml.Parent = recurseLoop; + + // The spooled data will now be using the original names from the anchor FetchXML node rather than the renamed + // versions from the Concatenate node, so rewrite the outer references + var outerReferences = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var outerRef in recurseLoop.OuterReferences) + { + var concatCol = concat.ColumnSet.Single(c => c.OutputColumn == outerRef.Key); + outerReferences[concatCol.SourceColumns[0]] = outerRef.Value; + } + + recurseLoop.OuterReferences = outerReferences; + + return concat; + } + + private condition GetForeignKeyFilter(FetchXmlScan anchorFetchXml, OneToManyRelationshipMetadata hierarchicalRelationship) + { + return GetFilter(anchorFetchXml, hierarchicalRelationship.ReferencingAttribute); + } + + private condition GetPrimaryKeyFilter(FetchXmlScan anchorFetchXml, EntityMetadata metadata) + { + return GetFilter(anchorFetchXml, metadata.PrimaryIdAttribute); + } + + private condition GetFilter(FetchXmlScan anchorFetchXml, string attribute) + { + if (anchorFetchXml.Entity.Items == null) + return null; + var anchorFilters = anchorFetchXml.Entity.Items.OfType().ToArray(); + if (anchorFilters.Length != 1) + return null; + if (anchorFilters[0].Items == null || anchorFilters[0].Items.Length != 1 || !(anchorFilters[0].Items[0] is condition anchorCondition)) + return null; + if (anchorCondition.attribute != attribute || anchorCondition.@operator != @operator.eq) + return null; + + return anchorCondition; + } + public override INodeSchema GetSchema(NodeCompilationContext context) { return Source.GetSchema(context); @@ -86,6 +383,9 @@ public override IEnumerable GetSources() protected override IEnumerable ExecuteInternal(NodeExecutionContext context) { + if (WithStack) + return ExecuteInternalWithStack(context); + // Build an internal hash table of the source indexed by the key column if (_hashTable == null) { @@ -102,8 +402,28 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont return matches; } + private IEnumerable ExecuteInternalWithStack(NodeExecutionContext context) + { + _stack = new Stack(); + + foreach (var entity in Source.Execute(context)) + { + _stack.Push(entity); + yield return entity; + } + } + + public IEnumerable GetWorkTable() + { + while (_stack.Count > 0) + yield return _stack.Pop(); + } + public override string ToString() { + if (WithStack) + return "Index Spool\r\n(Lazy Spool)"; + return "Index Spool\r\n(Eager Spool)"; } @@ -111,14 +431,18 @@ public override object Clone() { var clone = new IndexSpoolNode { - Source = (IDataExecutionPlanNodeInternal)Source.Clone(), KeyColumn = KeyColumn, SeekValue = SeekValue, _keySelector = _keySelector, - _seekSelector = _seekSelector + _seekSelector = _seekSelector, + WithStack = WithStack, }; + LastClone = clone; + + clone.Source = (IDataExecutionPlanNodeInternal)Source.Clone(); clone.Source.Parent = clone; + return clone; } } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/InsertNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/InsertNode.cs index 914232f4..de62f24b 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/InsertNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/InsertNode.cs @@ -5,6 +5,7 @@ using System.ServiceModel; using System.Threading; using System.Threading.Tasks; +using System.Xml; using Microsoft.Crm.Sdk.Messages; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.Xrm.Sdk; @@ -53,6 +54,11 @@ class InsertNode : BaseDmlNode [Category("Insert")] public override bool ContinueOnError { get; set; } + [Category("Insert")] + [DisplayName("Ignore Duplicate Key")] + [Description("Ignores any duplicate key errors encountered. Errors will be logged but the query will complete.")] + public bool IgnoreDuplicateKey { get; set; } + public override void AddRequiredColumns(NodeCompilationContext context, IList requiredColumns) { foreach (var col in ColumnMappings.Values) @@ -64,7 +70,40 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList hints) + { + IgnoreDuplicateKey = GetIgnoreDuplicateKey(context, hints); + + return base.FoldQuery(context, hints); + } + + private bool GetIgnoreDuplicateKey(NodeCompilationContext context, IList queryHints) + { + var ignoreDupKey = GetIgnoreDuplicateKeyHint(queryHints); + + if (!ignoreDupKey && LogicalName == "listmember") + { + ignoreDupKey = true; + context.Log("Duplicate entries will be silently ignored for listmember inserts"); + } + + return ignoreDupKey; + } + + private bool GetIgnoreDuplicateKeyHint(IList queryHints) + { + if (queryHints == null) + return false; + + var ignoreDupKey = queryHints + .OfType() + .Where(hint => hint.Hints.Any(s => s.Value.Equals("IGNORE_DUP_KEY", StringComparison.OrdinalIgnoreCase))) + .Any(); + + return ignoreDupKey; + } + + public override void Execute(NodeExecutionContext context, out int recordsAffected) { _executionCount++; @@ -101,7 +140,7 @@ public override string Execute(NodeExecutionContext context, out int recordsAffe using (_timer.Run()) { - return ExecuteDmlOperation( + ExecuteDmlOperation( dataSource, context.Options, entities, @@ -113,8 +152,8 @@ public override string Execute(NodeExecutionContext context, out int recordsAffe InProgressLowercase = "inserting", CompletedLowercase = "inserted" }, + context, out recordsAffected, - context.ParameterValues, LogicalName == "listmember" || meta.IsIntersect == true ? null : (Action) ((r) => SetIdentity(r, context.ParameterValues)) ); } @@ -199,6 +238,43 @@ private OrganizationRequest CreateInsertRequest(EntityMetadata meta, Entity enti return new CreateRequest { Target = insert }; } + protected override bool FilterErrors(NodeExecutionContext context, OrganizationRequest request, OrganizationServiceFault fault) + { + if (IgnoreDuplicateKey) + { + if (fault.ErrorCode == -2147220937 || fault.ErrorCode == -2147088238 || fault.ErrorCode == 409) + { + var logMessage = "Ignoring duplicate key error"; + + if (fault.ErrorCode == -2147088238) + { + // Duplicate alternate key. The duplicated values are available in the fault details + if (fault.ErrorDetails.TryGetValue("DuplicateAttributes", out var value) && + value is string duplicateAttributes) + { + var xml = new XmlDocument(); + xml.LoadXml(duplicateAttributes); + + logMessage += $". The duplicate values were ({String.Join(", ", xml.SelectNodes("/DuplicateAttributes/*").OfType().Select(attr => attr.InnerText))})"; + } + } + else + { + // Duplicate primary key. + if (request is AssociateRequest associate) + logMessage += $". The duplicate values were ({associate.Target.Id}, {associate.RelatedEntities[0].Id})"; + else if (request is CreateRequest create) + logMessage += $". The duplicate values were ({create.Target.Id})"; + } + + context.Log(logMessage); + return false; + } + } + + return true; + } + private void SetIdentity(OrganizationResponse response, IDictionary parameterValues) { var create = (CreateResponse)response; @@ -313,6 +389,7 @@ public override object Clone() Length = Length, LogicalName = LogicalName, MaxDOP = MaxDOP, + IgnoreDuplicateKey = IgnoreDuplicateKey, Source = (IExecutionPlanNodeInternal)Source.Clone(), Sql = Sql }; diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs index d4fdb871..b4daeeff 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/MergeJoinNode.cs @@ -217,6 +217,23 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext if (folded != this) return folded; + var hashJoin = new HashJoinNode + { + LeftSource = LeftSource, + RightSource = RightSource, + LeftAttribute = LeftAttribute, + RightAttribute = RightAttribute, + JoinType = JoinType, + AdditionalJoinCriteria = AdditionalJoinCriteria, + SemiJoin = SemiJoin + }; + + foreach (var kvp in DefinedValues) + hashJoin.DefinedValues.Add(kvp); + + hashJoin.LeftSource.Parent = hashJoin; + hashJoin.RightSource.Parent = hashJoin; + // Can't use a merge join if the join key types have different sort orders if (LeftAttribute != null && RightAttribute != null) { @@ -229,26 +246,7 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext var rightType = rightSchema.Schema[rightColumn].Type; if (!IsConsistentSortTypes(leftType, rightType)) - { - var hashJoin = new HashJoinNode - { - LeftSource = LeftSource, - RightSource = RightSource, - LeftAttribute = LeftAttribute, - RightAttribute = RightAttribute, - JoinType = JoinType, - AdditionalJoinCriteria = AdditionalJoinCriteria, - SemiJoin = SemiJoin - }; - - foreach (var kvp in DefinedValues) - hashJoin.DefinedValues.Add(kvp); - - hashJoin.LeftSource.Parent = hashJoin; - hashJoin.RightSource.Parent = hashJoin; - - return hashJoin; - } + return hashJoin.FoldQuery(context, hints); } // This is a many-to-many join if the left attribute is not unique @@ -301,27 +299,22 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext // If we couldn't fold the sorts, it's probably faster to use a hash join instead if we only want partial results var leftSort = LeftSource as SortNode; var rightSort = RightSource as SortNode; - if (Parent is TopNode && (leftSort != null || rightSort != null)) - { - var hashJoin = new HashJoinNode - { - LeftSource = leftSort?.Source ?? LeftSource, - RightSource = rightSort?.Source ?? RightSource, - LeftAttribute = LeftAttribute, - RightAttribute = RightAttribute, - JoinType = JoinType, - AdditionalJoinCriteria = AdditionalJoinCriteria, - SemiJoin = SemiJoin - }; - - foreach (var kvp in DefinedValues) - hashJoin.DefinedValues.Add(kvp); - - hashJoin.LeftSource.Parent = hashJoin; - hashJoin.RightSource.Parent = hashJoin; - - return hashJoin; - } + + if (leftSort == null && rightSort == null) + return this; + + hashJoin.LeftSource = leftSort?.Source ?? LeftSource; + hashJoin.RightSource = rightSort?.Source ?? RightSource; + + + var foldedHashJoin = hashJoin.FoldQuery(context, hints); + + if (Parent is TopNode || + leftSort != null && rightSort != null) + return foldedHashJoin; + + LeftSource.Parent = this; + RightSource.Parent = this; return this; } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NestedLoopNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NestedLoopNode.cs index c28072d8..ef8bb6be 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NestedLoopNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NestedLoopNode.cs @@ -60,7 +60,7 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont innerParameterTypes[kvp.Value] = leftSchema.Schema[kvp.Key].Type; } - rightCompilationContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes); + rightCompilationContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes, context.Log); } var innerParameters = context.ParameterValues; @@ -81,7 +81,7 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont var hasRight = false; - foreach (var right in RightSource.Execute(new NodeExecutionContext(context.DataSources, context.Options, innerParameterTypes, innerParameters))) + foreach (var right in RightSource.Execute(new NodeExecutionContext(context.DataSources, context.Options, innerParameterTypes, innerParameters, context.Log))) { if (rightSchema == null) { @@ -179,10 +179,13 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext LeftSource.Parent = this; var innerParameterTypes = GetInnerParameterTypes(leftSchema, context.ParameterTypes); - var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes); + var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes, context.Log); + var rightSchema = RightSource.GetSchema(innerContext); RightSource = RightSource.FoldQuery(innerContext, hints); RightSource.Parent = this; + FoldDefinedValues(rightSchema); + if (LeftSource is ConstantScanNode constant && constant.Schema.Count == 0 && constant.Values.Count == 1 && @@ -268,7 +271,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList rightSchema.ContainsColumn(col, out _)) @@ -284,7 +287,7 @@ protected override INodeSchema GetRightSchema(NodeCompilationContext context) { var leftSchema = LeftSource.GetSchema(context); var innerParameterTypes = GetInnerParameterTypes(leftSchema, context.ParameterTypes); - var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes); + var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes, context.Log); return RightSource.GetSchema(innerContext); } @@ -294,7 +297,7 @@ protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationConte ParseEstimate(leftEstimate, out var leftMin, out var leftMax, out var leftIsRange); var leftSchema = LeftSource.GetSchema(context); var innerParameterTypes = GetInnerParameterTypes(leftSchema, context.ParameterTypes); - var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes); + var innerContext = new NodeCompilationContext(context.DataSources, context.Options, innerParameterTypes, context.Log); var rightEstimate = RightSource.EstimateRowsOut(innerContext); ParseEstimate(rightEstimate, out var rightMin, out var rightMax, out var rightIsRange); diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NodeSchema.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NodeSchema.cs index 01999a90..d2e5b7d2 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NodeSchema.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/NodeSchema.cs @@ -77,15 +77,24 @@ public NodeSchema(INodeSchema copy) /// true if the column name exists, or false otherwise public bool ContainsColumn(string column, out string normalized) { - if (Schema.TryGetValue(column, out _)) + if (Aliases.TryGetValue(column, out var names)) { - normalized = Schema.Keys.Single(k => k.Equals(column, StringComparison.OrdinalIgnoreCase)); - return true; + if (names.Count > 1) + { + normalized = null; + return false; + } + + if (names.Count == 1) + { + normalized = names[0]; + return true; + } } - if (Aliases.TryGetValue(column, out var names) && names.Count == 1) + if (Schema.TryGetValue(column, out _)) { - normalized = names[0]; + normalized = Schema.Keys.Single(k => k.Equals(column, StringComparison.OrdinalIgnoreCase)); return true; } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/OpenJsonNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/OpenJsonNode.cs new file mode 100644 index 00000000..afd0f9a9 --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/OpenJsonNode.cs @@ -0,0 +1,455 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data.SqlTypes; +using System.Linq; +using System.Text; +using System.Text.Json; +using Microsoft.SqlServer.TransactSql.ScriptDom; +using Microsoft.Xrm.Sdk; + +namespace MarkMpn.Sql4Cds.Engine.ExecutionPlan +{ + class OpenJsonNode : BaseDataNode + { + private Func _jsonExpression; + private Func _pathExpression; + private Collation _jsonCollation; + private List> _conversions; + + private static readonly Collation _keyCollation; + + static OpenJsonNode() + { + _keyCollation = new Collation(null, 1033, SqlCompareOptions.BinarySort2, null); + } + + private OpenJsonNode() + { + } + + public OpenJsonNode(OpenJsonTableReference tvf, NodeCompilationContext context) + { + Alias = tvf.Alias?.Value; + Json = tvf.Variable.Clone(); + Path = tvf.RowPattern?.Clone(); + Schema = tvf.SchemaDeclarationItems.Count == 0 ? null : tvf.SchemaDeclarationItems; + + // Check expressions are string types and add conversions if not + var ecc = new ExpressionCompilationContext(context, null, null); + if (Json.GetType(ecc, out _) != typeof(SqlString)) + Json = new ConvertCall { Parameter = Json, DataType = DataTypeHelpers.NVarChar(Int32.MaxValue, context.PrimaryDataSource.DefaultCollation, CollationLabel.CoercibleDefault) }; + if (Path != null && Path.GetType(ecc, out _) != typeof(SqlString)) + Path = new ConvertCall { Parameter = Path, DataType = DataTypeHelpers.NVarChar(Int32.MaxValue, context.PrimaryDataSource.DefaultCollation, CollationLabel.CoercibleDefault) }; + + // Validate the schema definition + if (Schema != null) + { + var schema = GetSchema(context); + + // Set up the conversion functions to convert the string values extracted from the JSON to the type defined in the schema + var sourceType = DataTypeHelpers.NVarChar(Int32.MaxValue, Collation.USEnglish, CollationLabel.Implicit); + _conversions = schema.Schema + .Select(col => SqlTypeConverter.GetConversion(sourceType, col.Value.Type)) + .ToList(); + } + } + + /// + /// The alias for the data source + /// + [Category("Open JSON")] + [Description("The alias for the data source")] + public string Alias { get; set; } + + /// + /// The expression that provides the JSON to parse + /// + [Category("Open JSON")] + [Description("The expression that provides the JSON to parse")] + public ScalarExpression Json { get; set; } + + /// + /// The expression that defines the JSON path to the object or array to parse + /// + [Category("Open JSON")] + [Description("The expression that defines the JSON path to the object or array to parse")] + public ScalarExpression Path { get; set; } + + /// + /// The types of values to be returned + /// + [Browsable(false)] + public IList Schema { get; set; } + + public override void AddRequiredColumns(NodeCompilationContext context, IList requiredColumns) + { + } + + public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext context, IList hints) + { + var ecc = new ExpressionCompilationContext(context, null, null); + _jsonExpression = Json.Compile(ecc); + _pathExpression = Path?.Compile(ecc); + + return this; + } + + public override INodeSchema GetSchema(NodeCompilationContext context) + { + var columns = new ColumnList(); + var aliases = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + if (Schema == null) + { + if (_jsonCollation == null) + { + var ecc = new ExpressionCompilationContext(context, null, null); + Json.GetType(ecc, out var jsonType); + _jsonCollation = (jsonType as SqlDataTypeReferenceWithCollation)?.Collation ?? context.PrimaryDataSource.DefaultCollation; + } + + columns.Add(PrefixWithAlias("key", aliases), new ColumnDefinition(DataTypeHelpers.NVarChar(4000, _keyCollation, CollationLabel.Implicit), false, false)); + columns.Add(PrefixWithAlias("value", aliases), new ColumnDefinition(DataTypeHelpers.NVarChar(Int32.MaxValue, _jsonCollation, CollationLabel.Implicit), true, false)); + columns.Add(PrefixWithAlias("type", aliases), new ColumnDefinition(DataTypeHelpers.Int, false, false)); + } + else + { + foreach (var col in Schema) + { + var type = col.ColumnDefinition.DataType; + + if (type is SqlDataTypeReference sqlType && sqlType.SqlDataTypeOption.IsStringType()) + { + var collation = context.PrimaryDataSource.DefaultCollation; + + if (col.ColumnDefinition.Collation != null && !Collation.TryParse(col.ColumnDefinition.Collation.Value, out collation)) + throw new NotSupportedQueryFragmentException("Invalid collation", col.ColumnDefinition.Collation); + + type = new SqlDataTypeReferenceWithCollation + { + SqlDataTypeOption = sqlType.SqlDataTypeOption, + Collation = collation, + CollationLabel = col.ColumnDefinition.Collation == null ? CollationLabel.CoercibleDefault : CollationLabel.Implicit + }; + + foreach (var param in sqlType.Parameters) + ((SqlDataTypeReferenceWithCollation)type).Parameters.Add(param); + } + + if (col.AsJson) + { + if (!(type is SqlDataTypeReference nvarcharType) || + nvarcharType.SqlDataTypeOption != SqlDataTypeOption.NVarChar || + nvarcharType.Parameters.Count != 1 || + !(nvarcharType.Parameters[0] is MaxLiteral)) + { + throw new NotSupportedQueryFragmentException("AS JSON option can be specified only for column of nvarchar(max) type in WITH clause", col.ColumnDefinition.DataType); + } + } + + columns.Add(PrefixWithAlias(col.ColumnDefinition.ColumnIdentifier.Value, aliases), new ColumnDefinition(type, true, false)); + } + } + + var schema = new NodeSchema( + columns, + aliases, + null, + null + ); + + return schema; + } + + private string PrefixWithAlias(string name, IDictionary> aliases) + { + name = name.EscapeIdentifier(); + + var fullName = Alias == null ? name : (Alias.EscapeIdentifier() + "." + name); + + if (aliases != null) + { + if (!aliases.TryGetValue(name, out var alias)) + { + alias = new List(); + aliases[name] = alias; + } + + ((List)alias).Add(fullName); + } + + return fullName; + } + + public override IEnumerable GetSources() + { + return Array.Empty(); + } + + protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationContext context) + { + return new RowCountEstimate(10); + } + + protected override IEnumerable ExecuteInternal(NodeExecutionContext context) + { + var eec = new ExpressionExecutionContext(context); + + var json = (SqlString) _jsonExpression(eec); + + if (json.IsNull || json.Value.Length == 0) + yield break; + + string path; + + if (_pathExpression != null) + { + var pathValue = (SqlString)_pathExpression(eec); + + if (pathValue.IsNull) + yield break; + + path = pathValue.Value; + } + else + { + path = "$"; + } + + JsonPath jpath; + JsonElement jsonDoc; + JsonElement? jtoken; + + try + { + jpath = new JsonPath(path); + jsonDoc = JsonDocument.Parse(json.Value).RootElement; + + // Don't allow JSON scalar values, only objects or arrays + if (jsonDoc.ValueKind != JsonValueKind.Object && jsonDoc.ValueKind != JsonValueKind.Array) + throw new JsonException("JSON text is not properly formatted. Object or array is required"); + + jtoken = jpath.Evaluate(jsonDoc); + } + catch (JsonException ex) + { + throw new QueryExecutionException(ex.Message, ex); + } + + if (jtoken == null) + { + if (jpath.Mode == JsonPathMode.Lax) + yield break; + else + throw new QueryExecutionException("Property does not exist"); + } + + var schema = GetSchema(context); + var keyCol = PrefixWithAlias("key", null); + var valueCol = PrefixWithAlias("value", null); + var typeCol = PrefixWithAlias("type", null); + + JsonPath[] mappings = null; + + if (Schema != null) + { + mappings = Schema + .Select(col => col.Mapping as StringLiteral) + .Select(mapping => mapping == null ? null : new JsonPath(mapping.Value)) + .ToArray(); + } + + if (jtoken.Value.ValueKind == JsonValueKind.Object) + { + foreach (var prop in jtoken.Value.EnumerateObject()) + { + if (Schema == null) + { + var key = _keyCollation.ToSqlString(prop.Name); + var value = _jsonCollation.ToSqlString(GetValue(prop.Value)); + var type = GetType(prop.Value); + + yield return new Entity + { + [keyCol] = key, + [valueCol] = value, + [typeCol] = type + }; + } + else + { + yield return TokenToEntity(prop.Value, schema, mappings); + } + } + } + else if (jtoken.Value.ValueKind == JsonValueKind.Array) + { + var i = 0; + + foreach (var item in jtoken.Value.EnumerateArray()) + { + if (Schema == null) + { + var key = _keyCollation.ToSqlString(i.ToString()); + var value = _jsonCollation.ToSqlString(GetValue(item)); + var type = GetType(item); + + yield return new Entity + { + [keyCol] = key, + [valueCol] = value, + [typeCol] = type + }; + } + else + { + yield return TokenToEntity(item, schema, mappings); + } + + i++; + } + } + else + { + if (jpath.Mode == JsonPathMode.Lax) + yield break; + else + throw new QueryExecutionException("Not an object or array"); + } + } + + private Entity TokenToEntity(JsonElement token, INodeSchema schema, JsonPath[] mappings) + { + var result = new Entity(); + + for (var i = 0; i < schema.Schema.Count; i++) + { + var mapping = mappings[i]; + JsonElement? value; + + if (mapping != null) + { + value = mapping.Evaluate(token); + } + else if (token.ValueKind == JsonValueKind.Object) + { + if (token.TryGetProperty(Schema[i].ColumnDefinition.ColumnIdentifier.Value, out var prop)) + value = prop; + else + value = null; + } + else + { + value = null; + } + + string stringValue; + + if (Schema[i].AsJson) + { + if (value?.ValueKind == JsonValueKind.Array || value?.ValueKind == JsonValueKind.Object) + stringValue = value.Value.ToString(); + else if (mapping == null || mapping.Mode == JsonPathMode.Lax) + stringValue = null; + else + throw new QueryExecutionException("Object or array cannot be found in the specified JSON path"); + } + else + { + if (value?.ValueKind == JsonValueKind.Array || value?.ValueKind == JsonValueKind.Object || value == null) + { + if (mapping == null || mapping.Mode == JsonPathMode.Lax) + stringValue = null; + else if (value == null) + throw new QueryExecutionException("Property cannot be found on the specified JSON path"); + else + throw new QueryExecutionException("Object or array cannot be found in the specified JSON path"); + } + else + { + stringValue = GetValue(value.Value); + } + } + + var sqlStringValue = Collation.USEnglish.ToSqlString(stringValue); + var sqlValue = _conversions[i](sqlStringValue); + + result[PrefixWithAlias(Schema[i].ColumnDefinition.ColumnIdentifier.Value, null)] = sqlValue; + } + + return result; + } + + private string GetValue(JsonElement token) + { + switch (token.ValueKind) + { + case JsonValueKind.Object: + case JsonValueKind.Array: + return token.ToString(); + + case JsonValueKind.String: + return token.GetString(); + + case JsonValueKind.Number: + return token.GetDecimal().ToString(); + + case JsonValueKind.True: + case JsonValueKind.False: + return token.GetBoolean() ? "true" : "false"; + + default: + return null; + } + } + + private SqlInt32 GetType(JsonElement token) + { + switch (token.ValueKind) + { + case JsonValueKind.Null: + return 0; + + case JsonValueKind.String: + return 1; + + case JsonValueKind.Number: + return 2; + + case JsonValueKind.True: + case JsonValueKind.False: + return 3; + + case JsonValueKind.Array: + return 4; + + case JsonValueKind.Object: + return 5; + + default: + throw new QueryExecutionException($"Unexpected token type: {token.ValueKind}"); + } + } + + public override object Clone() + { + return new OpenJsonNode + { + Alias = Alias, + Json = Json.Clone(), + Path = Path.Clone(), + Schema = Schema, + _jsonExpression = _jsonExpression, + _pathExpression = _pathExpression, + _jsonCollation = _jsonCollation, + _conversions = _conversions, + }; + } + + public override string ToString() + { + return $"Table Valued Function\r\n[OPENJSON_{(Schema == null ? "DEFAULT" : "EXPLICIT")}]"; + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PartitionedAggregateNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PartitionedAggregateNode.cs index fa9857e4..9041e45d 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PartitionedAggregateNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PartitionedAggregateNode.cs @@ -103,8 +103,8 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont var minKey = GetMinMaxKey(fetchXmlNode, context, false); var maxKey = GetMinMaxKey(fetchXmlNode, context, true); - if (minKey.IsNull || maxKey.IsNull || minKey == maxKey) - throw new QueryExecutionException("Cannot partition query"); + if (minKey.IsNull || maxKey.IsNull || minKey >= maxKey) + throw new PartitionOverflowException(); // Add the filter to the FetchXML to partition the results fetchXmlNode.Entity.AddItem(new filter @@ -128,9 +128,6 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont partitionParameterTypes[kvp.Key] = kvp.Value; } - if (minKey > maxKey) - throw new QueryExecutionException("Cannot partition query"); - // Split recursively, add up values below & above split value if query returns successfully, or re-split on error // Range is > MinValue AND <= MaxValue, so start from just before first record to ensure the first record is counted var fullRange = new Partition @@ -167,7 +164,7 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont { var partitioner = Partitioner.Create(_queue.GetConsumingEnumerable(), EnumerablePartitionerOptions.NoBuffering); Parallel.ForEach(partitioner, - new ParallelOptions { MaxDegreeOfParallelism = maxDop }, + new ParallelOptions { MaxDegreeOfParallelism = maxDop, CancellationToken = context.Options.CancellationToken }, () => { var ds = new Dictionary @@ -202,7 +199,7 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont partitionParameterValues[kvp.Key] = kvp.Value; } - var partitionContext = new NodeExecutionContext(context.DataSources, context.Options, context.ParameterTypes, partitionParameterValues); + var partitionContext = new NodeExecutionContext(context.DataSources, context.Options, context.ParameterTypes, partitionParameterValues, context.Log); return new { Context = partitionContext, Fetch = fetch }; }, @@ -284,7 +281,10 @@ private void SplitPartition(Partition partition) // Fail if we get stuck on a particularly dense partition. If there's > 50K records in a 10 second window we probably // won't be able to split it successfully if (partition.MaxValue.Value < partition.MinValue.Value.AddSeconds(10)) + { + _queue.CompleteAdding(); throw new PartitionOverflowException(); + } // Start splitting partitions in half. Once we've done that a few times and are still hitting the 50K limit, start // pre-emptively splitting into smaller chunks diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PrintNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PrintNode.cs index 6b7f3c50..45eebaf2 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PrintNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/PrintNode.cs @@ -47,7 +47,7 @@ public object Clone() }; } - public string Execute(NodeExecutionContext context, out int recordsAffected) + public void Execute(NodeExecutionContext context, out int recordsAffected) { _executionCount++; recordsAffected = -1; @@ -56,10 +56,8 @@ public string Execute(NodeExecutionContext context, out int recordsAffected) { var value = (SqlString)_expression(new ExpressionExecutionContext(context)); - if (value.IsNull) - return null; - - return value.Value; + if (!value.IsNull) + context.Log(value.Value); } } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/RevertNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/RevertNode.cs index 5029ccb1..aa5b6a66 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/RevertNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/RevertNode.cs @@ -52,7 +52,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList /// Provides a rewindable cache of a data source /// - class TableSpoolNode : BaseDataNode, ISingleSourceExecutionPlanNode + class TableSpoolNode : BaseDataNode, ISingleSourceExecutionPlanNode, ISpoolProducerNode { class CachedList : IEnumerable { @@ -83,6 +83,8 @@ IEnumerator IEnumerable.GetEnumerator() } } + public TableSpoolNode() { } + private Entity[] _eagerSpool; private CachedList _lazyCache; @@ -96,6 +98,23 @@ IEnumerator IEnumerable.GetEnumerator() [DisplayName("Spool Type")] public SpoolType SpoolType { get; set; } + /// + /// Indicates if this spool is in place only for performance reasons + /// + internal bool IsPerformanceSpool { get; set; } + + /// + /// The node that produces data that this node should repeat + /// + /// + /// If this property is set, the node operates in Consumer mode. + /// + [Browsable(false)] + public ISpoolProducerNode Producer { get; set; } + + [Browsable(false)] + public ISpoolProducerNode LastClone { get; private set; } + internal int GetCount(NodeExecutionContext context) { if (_eagerSpool == null) @@ -106,6 +125,9 @@ internal int GetCount(NodeExecutionContext context) protected override IEnumerable ExecuteInternal(NodeExecutionContext context) { + if (Producer != null) + return Producer.GetWorkTable(); + if (SpoolType == SpoolType.Eager) { if (_eagerSpool == null) @@ -124,19 +146,23 @@ protected override IEnumerable ExecuteInternal(NodeExecutionContext cont public override IEnumerable GetSources() { - yield return Source; + if (Source != null) + yield return Source; } public override INodeSchema GetSchema(NodeCompilationContext context) { - return Source.GetSchema(context); + return (Source ?? Producer).GetSchema(context); } public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext context, IList hints) { + if (Source == null) + return this; + Source = Source.FoldQuery(context, hints); - if (hints != null && hints.Any(hint => hint.HintKind == OptimizerHintKind.NoPerformanceSpool)) + if (IsPerformanceSpool && hints != null && hints.Any(hint => hint.HintKind == OptimizerHintKind.NoPerformanceSpool)) return Source; Source.Parent = this; @@ -145,14 +171,22 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext public override void AddRequiredColumns(NodeCompilationContext context, IList requiredColumns) { - Source.AddRequiredColumns(context, requiredColumns); + Source?.AddRequiredColumns(context, requiredColumns); } protected override RowCountEstimate EstimateRowsOutInternal(NodeCompilationContext context) { + if (Source == null) + return new RowCountEstimate(1); + return Source.EstimateRowsOut(context); } + public IEnumerable GetWorkTable() + { + return (IEnumerable)_eagerSpool ?? _lazyCache; + } + public override string ToString() { return $"Table Spool\r\n({SpoolType} Spool)"; @@ -162,11 +196,18 @@ public override object Clone() { var clone = new TableSpoolNode { - Source = (IDataExecutionPlanNodeInternal)Source.Clone(), + Producer = Producer?.LastClone, SpoolType = SpoolType }; - clone.Source.Parent = clone; + LastClone = clone; + + if (Source != null) + { + clone.Source = (IDataExecutionPlanNodeInternal)Source.Clone(); + clone.Source.Parent = clone; + } + return clone; } } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/UpdateNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/UpdateNode.cs index ba4b063a..d20966a1 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/UpdateNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/UpdateNode.cs @@ -113,7 +113,7 @@ private bool GetUseLegacyUpdateMessages(NodeCompilationContext context, IList columnRe } } - protected override bool FilterErrors(OrganizationServiceFault fault) + protected override bool FilterErrors(NodeExecutionContext context, OrganizationRequest request, OrganizationServiceFault fault) { - // Ignore errors trying to delete records that don't exist - record may have been deleted by another + // Ignore errors trying to update records that don't exist - record may have been deleted by another // process in parallel. return fault.ErrorCode != -2147220969 && fault.ErrorCode != -2147185406 && fault.ErrorCode != -2147220969 && fault.ErrorCode != 404; } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/WaitForNode.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/WaitForNode.cs index f6bcb962..6f297c6e 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlan/WaitForNode.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlan/WaitForNode.cs @@ -55,7 +55,7 @@ public override void AddRequiredColumns(NodeCompilationContext context, IList _cteSubplans; public ExecutionPlanBuilder(IEnumerable dataSources, IQueryExecutionOptions options) { @@ -47,6 +48,11 @@ public ExecutionPlanBuilder(IEnumerable dataSources, IQueryExecution /// public bool EstimatedPlanOnly { get; set; } + /// + /// A callback function to log messages + /// + public Action Log { get; set; } + private DataSource PrimaryDataSource => DataSources[Options.PrimaryDataSource]; /// @@ -62,7 +68,7 @@ public IRootExecutionPlanNode[] Build(string sql, IDictionary(StringComparer.OrdinalIgnoreCase); _staticContext = new ExpressionCompilationContext(DataSources, Options, parameterTypes, null, null); - _nodeContext = new NodeCompilationContext(DataSources, Options, parameterTypes); + _nodeContext = new NodeCompilationContext(DataSources, Options, parameterTypes, Log); if (parameters != null) { @@ -97,7 +103,7 @@ public IRootExecutionPlanNode[] Build(string sql, IDictionary hints = null; + _cteSubplans = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (statement is StatementWithCtesAndXmlNamespaces stmtWithCtes) + { + hints = stmtWithCtes.OptimizerHints; + + if (stmtWithCtes.WithCtesAndXmlNamespaces != null) + { + foreach (var cte in stmtWithCtes.WithCtesAndXmlNamespaces.CommonTableExpressions) + { + if (_cteSubplans.ContainsKey(cte.ExpressionName.Value)) + throw new NotSupportedQueryFragmentException($"A CTE with the name '{cte.ExpressionName.Value}' has already been declared.", cte.ExpressionName); + + var cteValidator = new CteValidatorVisitor(); + cte.Accept(cteValidator); + + // Start by converting the anchor query to a subquery + var plan = ConvertSelectStatement(cteValidator.AnchorQuery, hints, null, null, _nodeContext); + + // Apply column aliases + if (cte.Columns.Count > 0) + { + plan.ExpandWildcardColumns(_nodeContext); + + if (cte.Columns.Count < plan.ColumnSet.Count) + throw new NotSupportedQueryFragmentException($"'{cteValidator.Name}' has more columns than were specified in the column list.", cte); + + if (cte.Columns.Count > plan.ColumnSet.Count) + throw new NotSupportedQueryFragmentException($"'{cteValidator.Name}' has fewer columns than were specified in the column list.", cte); + + for (var i = 0; i < cte.Columns.Count; i++) + plan.ColumnSet[i].OutputColumn = cte.Columns[i].Value; + } + + for (var i = 0; i < plan.ColumnSet.Count; i++) + { + if (plan.ColumnSet[i].OutputColumn == null) + throw new NotSupportedQueryFragmentException($"No column name was specified for column {i+1} of '{cteValidator.Name}'", cte); + } + + var anchorQuery = new AliasNode(plan, cte.ExpressionName, _nodeContext); + _cteSubplans.Add(cte.ExpressionName.Value, anchorQuery); + + if (cteValidator.RecursiveQueries.Count > 0) + { + anchorQuery = (AliasNode)anchorQuery.Clone(); + var ctePlan = anchorQuery.Source; + var anchorSchema = anchorQuery.GetSchema(_nodeContext); + + // Add a ComputeScalar node to add the initial recursion depth (0) + var recursionDepthField = _nodeContext.GetExpressionName(); + var initialRecursionDepthComputeScalar = new ComputeScalarNode + { + Source = ctePlan, + Columns = + { + [recursionDepthField] = new IntegerLiteral { Value = "0" } + } + }; + + // Add a ConcatenateNode to combine the anchor results with the recursion results + var recurseConcat = new ConcatenateNode + { + Sources = { initialRecursionDepthComputeScalar }, + }; + + foreach (var col in anchorQuery.ColumnSet) + { + var concatCol = new ConcatenateColumn + { + SourceColumns = { col.SourceColumn }, + OutputColumn = col.OutputColumn + }; + + recurseConcat.ColumnSet.Add(concatCol); + + col.SourceColumn = col.OutputColumn; + } + + recurseConcat.ColumnSet.Add(new ConcatenateColumn + { + SourceColumns = { recursionDepthField }, + OutputColumn = recursionDepthField + }); + + // Add an IndexSpool node in stack mode to enable the recursion + var recurseIndexStack = new IndexSpoolNode + { + Source = recurseConcat, + WithStack = true + }; + + // Pull the same records into the recursive loop + var recurseTableSpool = new TableSpoolNode + { + Producer = recurseIndexStack, + SpoolType = SpoolType.Lazy + }; + + // Increment the depth + var incrementedDepthField = _nodeContext.GetExpressionName(); + var incrementRecursionDepthComputeScalar = new ComputeScalarNode + { + Source = recurseTableSpool, + Columns = + { + [incrementedDepthField] = new BinaryExpression + { + FirstExpression = recursionDepthField.ToColumnReference(), + BinaryExpressionType = BinaryExpressionType.Add, + SecondExpression = new IntegerLiteral { Value = "1" } + } + } + }; + + // Use a nested loop to pass through the records to the recusive queries + var recurseLoop = new NestedLoopNode + { + LeftSource = incrementRecursionDepthComputeScalar, + JoinType = QualifiedJoinType.Inner, + OuterReferences = new Dictionary(StringComparer.OrdinalIgnoreCase) + }; + + // Capture all CTE fields in the outer references + foreach (var col in anchorSchema.Schema) + recurseLoop.OuterReferences[col.Key.SplitMultiPartIdentifier().Last().EscapeIdentifier()] = "@" + _nodeContext.GetExpressionName(); + + if (cteValidator.RecursiveQueries.Count > 1) + { + // Combine the results of each recursive query with a concat node + var concat = new ConcatenateNode(); + recurseLoop.RightSource = concat; + + foreach (var qry in cteValidator.RecursiveQueries) + { + var rightSource = ConvertRecursiveCTEQuery(qry, anchorSchema, cteValidator, recurseLoop.OuterReferences); + concat.Sources.Add(rightSource.Source); + + if (concat.Sources.Count == 1) + { + for (var i = 0; i < rightSource.ColumnSet.Count; i++) + { + var col = rightSource.ColumnSet[i]; + var expr = _nodeContext.GetExpressionName(); + concat.ColumnSet.Add(new ConcatenateColumn { OutputColumn = expr }); + recurseLoop.DefinedValues.Add(expr, expr); + recurseConcat.ColumnSet[i].SourceColumns.Add(expr); + } + } + + for (var i = 0; i < rightSource.ColumnSet.Count; i++) + concat.ColumnSet[i].SourceColumns.Add(rightSource.ColumnSet[i].SourceColumn); + } + } + else + { + var rightSource = ConvertRecursiveCTEQuery(cteValidator.RecursiveQueries[0], anchorSchema, cteValidator, recurseLoop.OuterReferences); + recurseLoop.RightSource = rightSource.Source; + + for (var i = 0; i < rightSource.ColumnSet.Count; i++) + { + var col = rightSource.ColumnSet[i]; + var expr = _nodeContext.GetExpressionName(); + + recurseLoop.DefinedValues.Add(expr, col.SourceColumn); + recurseConcat.ColumnSet[i].SourceColumns.Add(expr); + } + } + + // Ensure we don't get stuck in an infinite loop + var maxRecursion = stmtWithCtes.OptimizerHints + .OfType() + .Where(hint => hint.HintKind == OptimizerHintKind.MaxRecursion) + .FirstOrDefault() + ?.Value + ?.Value + ?? "100"; + + if (!Int32.TryParse(maxRecursion, out var max) || max < 0) + throw new NotSupportedQueryFragmentException("Invalid MAXRECURSION hint", stmtWithCtes.OptimizerHints + .OfType() + .Where(hint => hint.HintKind == OptimizerHintKind.MaxRecursion) + .First()); + + if (max > 0) + { + var assert = new AssertNode + { + Source = recurseLoop, + Assertion = e => + { + var depth = e.GetAttributeValue(incrementedDepthField); + return depth.Value < max; + }, + ErrorMessage = "Recursion depth exceeded" + }; + + // Combine the recursion results into the main results + recurseConcat.Sources.Add(assert); + } + else + { + recurseConcat.Sources.Add(recurseLoop); + } + + recurseConcat.ColumnSet.Last().SourceColumns.Add(incrementedDepthField); + + anchorQuery.Source = recurseIndexStack; + _cteSubplans[cte.ExpressionName.Value] = anchorQuery; + } + } + } + } if (statement is SelectStatement select) plans = new[] { ConvertSelectStatement(select) }; @@ -224,6 +443,24 @@ private void ConvertStatement(TSqlStatement statement, ExecutionPlanOptimizer op } } + private SelectNode ConvertRecursiveCTEQuery(QueryExpression queryExpression, INodeSchema anchorSchema, CteValidatorVisitor cteValidator, Dictionary outerReferences) + { + // Convert the query using the anchor query as a subquery to check for ambiguous column names + ConvertSelectStatement(queryExpression.Clone(), null, null, null, _nodeContext); + + // Remove recursive references from the FROM clause, moving join predicates to the WHERE clause + // If the recursive reference was in an unqualified join, replace it with (SELECT @Expr1, @Expr2) AS cte (field1, field2) + // Otherwise, remove it entirely and replace column references with variables + var cteReplacer = new RemoveRecursiveCTETableReferencesVisitor(cteValidator.Name, anchorSchema.Schema.Keys.ToArray(), outerReferences); + queryExpression.Accept(cteReplacer); + + // Convert the modified query. + var childContext = new NodeCompilationContext(_nodeContext, outerReferences.ToDictionary(kvp => kvp.Value, kvp => anchorSchema.Schema[cteValidator.Name.EscapeIdentifier() + "." + kvp.Key.EscapeIdentifier()].Type, StringComparer.OrdinalIgnoreCase)); + var converted = ConvertSelectStatement(queryExpression, null, null, null, childContext); + converted.ExpandWildcardColumns(childContext); + return converted; + } + private IRootExecutionPlanNodeInternal[] ConvertExecuteStatement(ExecuteStatement execute) { var nodes = new List(); @@ -1652,6 +1889,9 @@ private IRootExecutionPlanNodeInternal ConvertSelectStatement(SelectStatement se if (tdsEndpointCompatibilityVisitor.IsCompatible && hintCompatibilityVisitor.TdsCompatible) { + if (tdsEndpointCompatibilityVisitor.RequiresCteRewrite) + select.Accept(new ReplaceCtesWithSubqueriesVisitor()); + select.ScriptTokenStream = null; var sql = new SqlNode { @@ -1679,9 +1919,6 @@ private IRootExecutionPlanNodeInternal ConvertSelectStatement(SelectStatement se if (select.On != null) throw new NotSupportedQueryFragmentException("Unsupported ON clause", select.On); - if (select.WithCtesAndXmlNamespaces != null) - throw new NotSupportedQueryFragmentException("Unsupported CTE clause", select.WithCtesAndXmlNamespaces); - var variableAssignments = new List(); SelectElement firstNonSetSelectElement = null; @@ -1807,6 +2044,8 @@ private SelectNode ConvertBinaryQuery(BinaryQueryExpression binary, IList() } } : ConvertFromClause(querySpec.FromClause, hints, querySpec, outerSchema, outerReferences, context); + var node = querySpec.FromClause == null || querySpec.FromClause.TableReferences.Count == 0 ? new ConstantScanNode { Values = { new Dictionary() } } : ConvertFromClause(querySpec.FromClause, hints, querySpec, outerSchema, outerReferences, context); var logicalSchema = node.GetSchema(context); node = ConvertInSubqueries(node, hints, querySpec, context, outerSchema, outerReferences); @@ -2069,7 +2310,7 @@ private IDataExecutionPlanNodeInternal ConvertInSubqueries(IDataExecutionPlanNod else { // We need the inner list to be distinct to avoid creating duplicates during the join - var innerSchema = innerQuery.Source.GetSchema(new NodeCompilationContext(DataSources, Options, parameters)); + var innerSchema = innerQuery.Source.GetSchema(new NodeCompilationContext(DataSources, Options, parameters, Log)); if (innerQuery.ColumnSet[0].SourceColumn != innerSchema.PrimaryKey && !(innerQuery.Source is DistinctNode)) { innerQuery.Source = new DistinctNode @@ -2168,7 +2409,7 @@ private IDataExecutionPlanNodeInternal ConvertExistsSubqueries(IDataExecutionPla var innerContext = new NodeCompilationContext(context, parameters); var references = new Dictionary(); var innerQuery = ConvertSelectStatement(existsSubquery.Subquery.QueryExpression, hints, schema, references, innerContext); - var innerSchema = innerQuery.Source.GetSchema(new NodeCompilationContext(DataSources, Options, parameters)); + var innerSchema = innerQuery.Source.GetSchema(new NodeCompilationContext(DataSources, Options, parameters, Log)); var innerSchemaPrimaryKey = innerSchema.PrimaryKey; // Create the join @@ -3102,7 +3343,7 @@ private ColumnReferenceExpression ConvertScalarSubqueries(TSqlFragment expressio { if (EstimateRowsOut(node, context) > 1) { - var spool = new TableSpoolNode { Source = loopRightSource, SpoolType = SpoolType.Lazy }; + var spool = new TableSpoolNode { Source = loopRightSource, SpoolType = SpoolType.Lazy, IsPerformanceSpool = true }; loopRightSource = spool; } } @@ -3213,8 +3454,8 @@ private bool UseMergeJoin(IDataExecutionPlanNodeInternal node, IDataExecutionPla if (outerKey == null) return false; - var outerSchema = node.GetSchema(new NodeCompilationContext(DataSources, Options, null)); - var innerSchema = subNode.GetSchema(new NodeCompilationContext(DataSources, Options, null)); + var outerSchema = node.GetSchema(new NodeCompilationContext(DataSources, Options, null, Log)); + var innerSchema = subNode.GetSchema(new NodeCompilationContext(DataSources, Options, null, Log)); if (!outerSchema.ContainsColumn(outerKey, out outerKey) || !innerSchema.ContainsColumn(innerKey, out innerKey)) @@ -3287,7 +3528,7 @@ private bool UseMergeJoin(IDataExecutionPlanNodeInternal node, IDataExecutionPla if (semiJoin) { // Regenerate the schema after changing the alias - innerSchema = subNode.GetSchema(new NodeCompilationContext(DataSources, Options, null)); + innerSchema = subNode.GetSchema(new NodeCompilationContext(DataSources, Options, null, Log)); if (innerSchema.PrimaryKey != rightAttribute.GetColumnName() && !(merge.RightSource is DistinctNode)) { @@ -3380,7 +3621,8 @@ private void InsertCorrelatedSubquerySpool(ISingleSourceExecutionPlanNode node, var spool = new TableSpoolNode { Source = lastCorrelatedStep.Source, - SpoolType = SpoolType.Lazy + SpoolType = SpoolType.Lazy, + IsPerformanceSpool = true }; lastCorrelatedStep.Source = spool; @@ -3459,6 +3701,16 @@ private IDataExecutionPlanNodeInternal ConvertTableReference(TableReference refe { if (reference is NamedTableReference table) { + if (table.SchemaObject.Identifiers.Count == 1 && _cteSubplans.TryGetValue(table.SchemaObject.BaseIdentifier.Value, out var cteSubplan)) + { + var aliasNode = (AliasNode)cteSubplan.Clone(); + + if (table.Alias != null) + aliasNode.Alias = table.Alias.Value; + + return aliasNode; + } + var dataSource = SelectDataSource(table.SchemaObject); var entityName = table.SchemaObject.BaseIdentifier.Value; @@ -3595,6 +3847,11 @@ private IDataExecutionPlanNodeInternal ConvertTableReference(TableReference refe var rhsSchema = rhs.GetSchema(context); var fixedValueColumns = GetFixedValueColumnsFromWhereClause(query, lhsSchema, rhsSchema); + // Capture any references to data from an outer query + // Use a temporary NestedLoopNode to include the full schema available within this query so far to ensure columns are + // used from this query in preference to the outer query. + CaptureOuterReferences(outerSchema, new NestedLoopNode { LeftSource = lhs, RightSource = rhs }, join.SearchCondition, context, outerReferences); + var joinConditionVisitor = new JoinConditionVisitor(lhsSchema, rhsSchema, fixedValueColumns); join.SearchCondition.Accept(joinConditionVisitor); @@ -3696,7 +3953,7 @@ private IDataExecutionPlanNodeInternal ConvertTableReference(TableReference refe else { // Spool the inner table so the results can be reused by the nested loop - rhs = new TableSpoolNode { Source = rhs, SpoolType = SpoolType.Eager }; + rhs = new TableSpoolNode { Source = rhs, SpoolType = SpoolType.Eager, IsPerformanceSpool = true }; joinNode = new NestedLoopNode { @@ -3845,6 +4102,48 @@ private IDataExecutionPlanNodeInternal ConvertTableReference(TableReference refe return loop; } + if (reference is OpenJsonTableReference openJson) + { + // Capture any references to data from an outer query + CaptureOuterReferences(outerSchema, null, openJson, context, outerReferences); + + // Convert any scalar subqueries in the parameters to its own execution plan, and capture the references from those plans + // as parameters to be passed to the function + IDataExecutionPlanNodeInternal source = new ConstantScanNode { Values = { new Dictionary() } }; + var computeScalar = new ComputeScalarNode { Source = source }; + + ConvertScalarSubqueries(openJson.Variable, hints, ref source, computeScalar, context, openJson); + + if (openJson.RowPattern != null) + ConvertScalarSubqueries(openJson.RowPattern, hints, ref source, computeScalar, context, openJson); + + if (source is ConstantScanNode) + source = null; + else if (computeScalar.Columns.Count > 0) + source = computeScalar; + + var scalarSubquerySchema = source?.GetSchema(context); + var scalarSubqueryReferences = new Dictionary(); + CaptureOuterReferences(scalarSubquerySchema, null, openJson, context, scalarSubqueryReferences); + + var execute = new OpenJsonNode(openJson, context); + + if (source == null) + return execute; + + // If we've got any subquery parameters we need to use a loop to pass them to the function + var loop = new NestedLoopNode + { + LeftSource = source, + RightSource = execute, + JoinType = QualifiedJoinType.Inner, + OuterReferences = scalarSubqueryReferences, + OutputLeftSchema = false, + }; + + return loop; + } + throw new NotSupportedQueryFragmentException("Unhandled table reference", reference); } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlanNodeTypeDescriptor.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlanNodeTypeDescriptor.cs index ec61670c..33347c8f 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlanNodeTypeDescriptor.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlanNodeTypeDescriptor.cs @@ -304,7 +304,7 @@ private static string GetPropertyName(System.Collections.IList list, object item .SingleOrDefault(p => p.GetCustomAttribute() != null); if (dictionaryKeyProperty != null) - return dictionaryKeyProperty.GetValue(item).ToString(); + return dictionaryKeyProperty.GetValue(item)?.ToString() ?? " "; return index.ToString().PadLeft((int)Math.Ceiling(Math.Log10(list.Count)), '0'); } diff --git a/MarkMpn.Sql4Cds.Engine/ExecutionPlanOptimizer.cs b/MarkMpn.Sql4Cds.Engine/ExecutionPlanOptimizer.cs index 9807afbe..1b8f787b 100644 --- a/MarkMpn.Sql4Cds.Engine/ExecutionPlanOptimizer.cs +++ b/MarkMpn.Sql4Cds.Engine/ExecutionPlanOptimizer.cs @@ -17,12 +17,13 @@ namespace MarkMpn.Sql4Cds.Engine /// class ExecutionPlanOptimizer { - public ExecutionPlanOptimizer(IDictionary dataSources, IQueryExecutionOptions options, IDictionary parameterTypes, bool compileConditions) + public ExecutionPlanOptimizer(IDictionary dataSources, IQueryExecutionOptions options, IDictionary parameterTypes, bool compileConditions, Action log) { DataSources = dataSources; Options = options; ParameterTypes = parameterTypes; CompileConditions = compileConditions; + Log = log; } public IDictionary DataSources { get; } @@ -33,6 +34,8 @@ public ExecutionPlanOptimizer(IDictionary dataSources, IQuer public bool CompileConditions { get; } + public Action Log { get; } + /// /// Optimizes an execution plan /// @@ -49,7 +52,7 @@ public IRootExecutionPlanNodeInternal[] Optimize(IRootExecutionPlanNodeInternal hints.Add(new ConditionalNode.DoNotCompileConditionsHint()); } - var context = new NodeCompilationContext(DataSources, Options, ParameterTypes); + var context = new NodeCompilationContext(DataSources, Options, ParameterTypes, Log); // Move any additional operators down to the FetchXml var bypassOptimization = hints != null && hints.OfType().Any(list => list.Hints.Any(h => h.Value.Equals("DEBUG_BYPASS_OPTIMIZATION", StringComparison.OrdinalIgnoreCase))); diff --git a/MarkMpn.Sql4Cds.Engine/ExpressionFunctions.cs b/MarkMpn.Sql4Cds.Engine/ExpressionFunctions.cs index 610b7266..0ea35309 100644 --- a/MarkMpn.Sql4Cds.Engine/ExpressionFunctions.cs +++ b/MarkMpn.Sql4Cds.Engine/ExpressionFunctions.cs @@ -3,7 +3,6 @@ using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.VisualBasic; using Microsoft.Xrm.Sdk; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Data.SqlTypes; @@ -18,6 +17,7 @@ using System.Xml.XPath; using Wmhelp.XPath2; using Wmhelp.XPath2.Value; +using System.Text.Json; #if NETCOREAPP using Microsoft.PowerPlatform.Dataverse.Client; #else @@ -52,48 +52,46 @@ public static SqlEntityReference CreateLookup(SqlString logicalName, SqlGuid id) /// A JSON path that specifies the property to extract /// Returns a single text value of type nvarchar(4000) [MaxLength(4000)] + [CollationSensitive] public static SqlString Json_Value(SqlString json, SqlString jpath) { if (json.IsNull || jpath.IsNull) return SqlString.Null; var path = jpath.Value; - var lax = !path.StartsWith("strict ", StringComparison.OrdinalIgnoreCase); - - if (path.StartsWith("strict ", StringComparison.OrdinalIgnoreCase)) - path = path.Substring(7); - else if (path.StartsWith("lax ", StringComparison.OrdinalIgnoreCase)) - path = path.Substring(4); - + try { - var jsonDoc = JToken.Parse(json.Value); - var jtoken = jsonDoc.SelectToken(path); + var jsonPath = new JsonPath(path); + var jsonDoc = JsonDocument.Parse(json.Value); + var jtoken = jsonPath.Evaluate(jsonDoc.RootElement); if (jtoken == null) { - if (lax) + if (jsonPath.Mode == JsonPathMode.Lax) return SqlString.Null; else throw new QueryExecutionException("Property does not exist"); } - if (jtoken.Type == JTokenType.Object || jtoken.Type == JTokenType.Array) + switch (jtoken.Value.ValueKind) { - if (lax) + case JsonValueKind.Object: + case JsonValueKind.Array: + if (jsonPath.Mode == JsonPathMode.Lax) + return SqlString.Null; + else + throw new QueryExecutionException("Not a scalar value"); + + case JsonValueKind.Null: return SqlString.Null; - else - throw new QueryExecutionException("Not a scalar value"); } - var value = jtoken.Value(); - - if (value == null) - return SqlString.Null; + var value = jtoken.Value.ToString(); if (value.Length > 4000) { - if (lax) + if (jsonPath.Mode == JsonPathMode.Lax) return SqlString.Null; else throw new QueryExecutionException("Value too long"); @@ -107,6 +105,53 @@ public static SqlString Json_Value(SqlString json, SqlString jpath) } } + /// + /// Extracts an object or an array from a JSON string + /// + /// An expression containing the JSON document to parse + /// A JSON path that specifies the property to extract + /// Returns a JSON fragment of type nvarchar(max) + [CollationSensitive] + public static SqlString Json_Query(SqlString json, SqlString jpath) + { + if (json.IsNull || jpath.IsNull) + return SqlString.Null; + + var path = jpath.Value; + + try + { + var jsonPath = new JsonPath(path); + var jsonDoc = JsonDocument.Parse(json.Value); + var jtoken = jsonPath.Evaluate(jsonDoc.RootElement); + + if (jtoken == null) + { + if (jsonPath.Mode == JsonPathMode.Lax) + return SqlString.Null; + else + throw new QueryExecutionException("Property does not exist"); + } + + switch (jtoken.Value.ValueKind) + { + case JsonValueKind.Object: + case JsonValueKind.Array: + return new SqlString(jtoken.Value.ToString(), json.LCID, json.SqlCompareOptions); + + default: + if (jsonPath.Mode == JsonPathMode.Lax) + return SqlString.Null; + else + throw new QueryExecutionException("Not a scalar value"); + } + } + catch (Newtonsoft.Json.JsonException ex) + { + throw new QueryExecutionException(ex.Message, ex); + } + } + /// /// Tests whether a specified SQL/JSON path exists in the input JSON string. /// @@ -120,16 +165,11 @@ public static SqlBoolean Json_Path_Exists(SqlString json, SqlString jpath) var path = jpath.Value; - if (path.StartsWith("strict ", StringComparison.OrdinalIgnoreCase)) - path = path.Substring(7); - else if (path.StartsWith("lax ", StringComparison.OrdinalIgnoreCase)) - path = path.Substring(4); - try { - - var jsonDoc = JToken.Parse(json.Value); - var jtoken = jsonDoc.SelectToken(path); + var jsonPath = new JsonPath(path); + var jsonDoc = JsonDocument.Parse(json.Value); + var jtoken = jsonPath.Evaluate(jsonDoc.RootElement); return jtoken != null; } @@ -1005,6 +1045,77 @@ public static SqlVariant Sql_Variant_Property(SqlVariant expression, SqlString p return SqlVariant.Null; } + + /// + /// Tests whether a string contains valid JSON + /// + /// The string to test + /// null if is null, true if the input is a valid JSON object or array or false otherwise + public static SqlBoolean IsJson(SqlString json) + { + if (json.IsNull) + return SqlBoolean.Null; + + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json.Value).AsSpan()); + JsonElement? element; + + try + { + if (!JsonElement.TryParseValue(ref reader, out element) || element == null) + return false; + } + catch (JsonException) + { + return false; + } + + if (!reader.IsFinalBlock) + return false; + + return element.Value.ValueKind == JsonValueKind.Array || element.Value.ValueKind == JsonValueKind.Object; + } + + /// + /// Tests whether a string contains valid JSON + /// + /// The string to test + /// Specifies the JSON type to check in the input + /// Returns true if the string contains valid JSON; otherwise, returns false. Returns null if expression is null + public static SqlBoolean IsJson(SqlString json, SqlString type) + { + if (json.IsNull) + return SqlBoolean.Null; + + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json.Value).AsSpan()); + JsonElement? element; + + try + { + if (!JsonElement.TryParseValue(ref reader, out element) || element == null) + return false; + } + catch (JsonException) + { + return false; + } + + if (!reader.IsFinalBlock) + return false; + + if (type.Value.Equals("VALUE", StringComparison.OrdinalIgnoreCase)) + return true; + + if (type.Value.Equals("ARRAY", StringComparison.OrdinalIgnoreCase)) + return element.Value.ValueKind == JsonValueKind.Array; + + if (type.Value.Equals("OBJECT", StringComparison.OrdinalIgnoreCase)) + return element.Value.ValueKind == JsonValueKind.Object; + + if (type.Value.Equals("SCALAR", StringComparison.OrdinalIgnoreCase)) + return element.Value.ValueKind == JsonValueKind.String || element.Value.ValueKind == JsonValueKind.Number; + + return false; + } } /// diff --git a/MarkMpn.Sql4Cds.Engine/FetchXml2Sql.cs b/MarkMpn.Sql4Cds.Engine/FetchXml2Sql.cs index 73be4b6b..66777927 100644 --- a/MarkMpn.Sql4Cds.Engine/FetchXml2Sql.cs +++ b/MarkMpn.Sql4Cds.Engine/FetchXml2Sql.cs @@ -1674,7 +1674,7 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu case @operator.eqorunder: case @operator.notunder: { - var cte = GetUnderCte(meta, new Guid(condition.value), ctes); + var cte = GetUnderCte(meta, new Guid(condition.value), ctes, condition.@operator == @operator.under); var inPred = new InPredicate { Expression = field, @@ -1692,7 +1692,6 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu { Identifiers = { - new Identifier { Value = cte.ExpressionName.Value }, new Identifier { Value = meta.PrimaryIdAttribute } } } @@ -1714,25 +1713,6 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu } } } - }, - WhereClause = condition.@operator != @operator.under ? null : new WhereClause - { - SearchCondition = new BooleanComparisonExpression - { - FirstExpression = new ColumnReferenceExpression - { - MultiPartIdentifier = new MultiPartIdentifier - { - Identifiers = - { - new Identifier { Value = cte.ExpressionName.Value }, - new Identifier { Value = "Level" } - } - } - }, - ComparisonType = BooleanComparisonType.NotEqualToBrackets, - SecondExpression = new IntegerLiteral { Value = "0" } - } } } } @@ -1756,7 +1736,7 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu case @operator.above: case @operator.eqorabove: { - var cte = GetAboveCte(meta, new Guid(condition.value), ctes); + var cte = GetAboveCte(meta, new Guid(condition.value), ctes, condition.@operator == @operator.above); var inPred = new InPredicate { Expression = field, @@ -1774,7 +1754,6 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu { Identifiers = { - new Identifier { Value = cte.ExpressionName.Value }, new Identifier { Value = meta.PrimaryIdAttribute } } } @@ -1796,25 +1775,6 @@ private static BooleanExpression GetCondition(IOrganizationService org, IAttribu } } } - }, - WhereClause = condition.@operator != @operator.above ? null : new WhereClause - { - SearchCondition = new BooleanComparisonExpression - { - FirstExpression = new ColumnReferenceExpression - { - MultiPartIdentifier = new MultiPartIdentifier - { - Identifiers = - { - new Identifier { Value = cte.ExpressionName.Value }, - new Identifier { Value = "Level" } - } - } - }, - ComparisonType = BooleanComparisonType.NotEqualToBrackets, - SecondExpression = new IntegerLiteral { Value = "0" } - } } } } @@ -1999,19 +1959,20 @@ private static FunctionCall DatePart(string datePart, ScalarExpression date) /// The metadata of the entity to recurse in /// The unique identifier of the starting record to recurse down from /// The details of all the CTEs already in the query + /// Indicates if the starting record should be excluded from the results /// The CTE that represents the required query /// /// Generates a CTE like: /// - /// account_hierarchical([Level], AccountId, ParentAccountId) AS + /// account_hierarchical(AccountId) AS /// ( - /// SELECT 0, accountid, parentaccountid FROM account WHERE accountid = 'guid' + /// SELECT accountid FROM account WHERE accountid = 'guid' /// UNION ALL - /// SELECT Level + 1, account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid + /// SELECT account.accountid FROM account INNER JOIN account_hierarchical ON account.parentaccountid = account_hierarchical.accountid /// - private static CommonTableExpression GetUnderCte(EntityMetadata meta, Guid guid, IDictionary ctes) + private static CommonTableExpression GetUnderCte(EntityMetadata meta, Guid guid, IDictionary ctes, bool excludeAnchor) { - return GetCte(meta, guid, false, ctes); + return GetCte(meta, guid, false, ctes, excludeAnchor); } /// @@ -2020,19 +1981,20 @@ private static CommonTableExpression GetUnderCte(EntityMetadata meta, Guid guid, /// The metadata of the entity to recurse in /// The unique identifier of the starting record to recurse down from /// The details of all the CTEs already in the query + /// Indicates if the starting record should be excluded from the results /// The CTE that represents the required query /// /// Generates a CTE like: /// - /// account_hierarchical([Level], AccountId, ParentAccountId) AS + /// account_hierarchical(AccountId, ParentAccountId) AS /// ( - /// SELECT 0, accountid, parentaccountid FROM account WHERE accountid = 'guid' + /// SELECT accountid, parentaccountid FROM account WHERE accountid = 'guid' /// UNION ALL - /// SELECT Level + 1, account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid + /// SELECT account.accountid, account.parentaccountid FROM account INNER JOIN account_hierarchical ON account.accountid = account_hierarchical.parentaccountid /// - private static CommonTableExpression GetAboveCte(EntityMetadata meta, Guid guid, IDictionary ctes) + private static CommonTableExpression GetAboveCte(EntityMetadata meta, Guid guid, IDictionary ctes, bool excludeAnchor) { - return GetCte(meta, guid, true, ctes); + return GetCte(meta, guid, true, ctes, excludeAnchor); } /// @@ -2043,7 +2005,7 @@ private static CommonTableExpression GetAboveCte(EntityMetadata meta, Guid guid, /// Indicates if the CTE should find records above the selected record (true) or below (false) /// The details of all the CTEs already in the query /// The CTE that represents the required query - private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool above, IDictionary ctes) + private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool above, IDictionary ctes, bool excludeAnchor) { if (meta == null) throw new DisconnectedException(); @@ -2070,7 +2032,6 @@ private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool ExpressionName = new Identifier { Value = name }, Columns = { - new Identifier { Value = "Level" }, new Identifier { Value = meta.PrimaryIdAttribute }, new Identifier { Value = parentLookupAttribute } }, @@ -2080,10 +2041,6 @@ private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool { SelectElements = { - new SelectScalarExpression - { - Expression = new IntegerLiteral { Value = "0" } - }, new SelectScalarExpression { Expression = new ColumnReferenceExpression @@ -2137,7 +2094,7 @@ private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool { Identifiers = { - new Identifier { Value = meta.PrimaryIdAttribute } + new Identifier { Value = excludeAnchor && !above ? parentLookupAttribute : meta.PrimaryIdAttribute } } } }, @@ -2152,24 +2109,6 @@ private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool { SelectElements = { - new SelectScalarExpression - { - Expression = new BinaryExpression - { - FirstExpression = new ColumnReferenceExpression - { - MultiPartIdentifier = new MultiPartIdentifier - { - Identifiers = - { - new Identifier { Value = "Level" } - } - } - }, - BinaryExpressionType = BinaryExpressionType.Add, - SecondExpression = new IntegerLiteral { Value = "1" } - } - }, new SelectScalarExpression { Expression = new ColumnReferenceExpression @@ -2259,6 +2198,75 @@ private static CommonTableExpression GetCte(EntityMetadata meta, Guid guid, bool } }; + if (excludeAnchor && above) + { + // Need to include a join in the anchor query to find the records above the source record but not including that record + var query = (BinaryQueryExpression)cte.QueryExpression; + var anchorQuery = (QuerySpecification)query.FirstQueryExpression; + var filter = (BooleanComparisonExpression)anchorQuery.WhereClause.SearchCondition; + var field = (ColumnReferenceExpression)filter.FirstExpression; + + anchorQuery.FromClause.TableReferences[0] = new QualifiedJoin + { + FirstTableReference = anchorQuery.FromClause.TableReferences[0], + QualifiedJoinType = QualifiedJoinType.Inner, + SecondTableReference = new NamedTableReference + { + SchemaObject = new SchemaObjectName + { + Identifiers = + { + new Identifier { Value = meta.LogicalName } + } + }, + Alias = new Identifier { Value = "anchor" } + }, + SearchCondition = new BooleanComparisonExpression + { + FirstExpression = new ColumnReferenceExpression + { + MultiPartIdentifier = new MultiPartIdentifier + { + Identifiers = + { + new Identifier { Value = meta.LogicalName }, + new Identifier { Value = meta.PrimaryIdAttribute } + } + } + }, + ComparisonType = BooleanComparisonType.Equals, + SecondExpression = new ColumnReferenceExpression + { + MultiPartIdentifier = new MultiPartIdentifier + { + Identifiers = + { + new Identifier { Value = "anchor" }, + new Identifier { Value = parentLookupAttribute } + } + } + } + } + }; + + ((ColumnReferenceExpression)((SelectScalarExpression)anchorQuery.SelectElements[0]).Expression).MultiPartIdentifier.Identifiers.Insert(0, new Identifier { Value = meta.LogicalName }); + ((ColumnReferenceExpression)((SelectScalarExpression)anchorQuery.SelectElements[1]).Expression).MultiPartIdentifier.Identifiers.Insert(0, new Identifier { Value = meta.LogicalName }); + field.MultiPartIdentifier.Identifiers.Insert(0, new Identifier { Value = "anchor" }); + } + + if (!above) + { + // Don't need the parent attribute in the CTE for "under" queries + cte.Columns.RemoveAt(1); + + var query = (BinaryQueryExpression)cte.QueryExpression; + var anchorQuery = (QuerySpecification)query.FirstQueryExpression; + var recursiveQuery = (QuerySpecification)query.SecondQueryExpression; + + anchorQuery.SelectElements.RemoveAt(1); + recursiveQuery.SelectElements.RemoveAt(1); + } + ctes.Add(name, cte); return cte; diff --git a/MarkMpn.Sql4Cds.Engine/JsonPath.cs b/MarkMpn.Sql4Cds.Engine/JsonPath.cs new file mode 100644 index 00000000..a500733c --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/JsonPath.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; + +namespace MarkMpn.Sql4Cds.Engine +{ + /// + /// Handles navigating JSON documents using a JSON Path expression + /// + /// + /// The JSON Path syntax supported by SQL Server is subtely different to that implemented by + /// JSON.NET, so to keep compatibility with the various T-SQL samples we need to use this class + /// instead of the built-in method. + /// https://learn.microsoft.com/en-us/sql/relational-databases/json/json-path-expressions-sql-server?view=sql-server-ver16 + /// + class JsonPath + { + private readonly JsonPathPart[] _parts; + private readonly JsonPathMode _mode; + + public JsonPath(string expression) + { + _parts = Parse(expression, out _mode); + } + + /// + /// Returns the mode the path should be evaluated in + /// + public JsonPathMode Mode { get => _mode; } + + /// + /// Finds the token matching the path + /// + /// The token to start matching from + /// The token matching the path, or null if no match is found + public JsonElement? Evaluate(JsonElement token) + { + foreach (var part in _parts) + { + var match = part.Match(token); + + if (match == null) + return null; + + token = match.Value; + } + + return token; + } + + private static JsonPathPart[] Parse(string expression, out JsonPathMode mode) + { + mode = JsonPathMode.Lax; + + if (expression.StartsWith("lax ")) + { + expression = expression.Substring(4); + } + else if (expression.StartsWith("strict ")) + { + expression = expression.Substring(7); + mode = JsonPathMode.Strict; + } + + var parts = new List(); + + for (var i = 0; i < expression.Length; i++) + { + if (i == 0 && expression[i] == '$') + { + parts.Add(new ContextJsonPathPart()); + } + else if (i > 0 && expression[i] == '.') + { + // Start of a property key + i++; + + if (i == expression.Length) + throw new JsonException($"Invalid JSON path - missing property name after '.' at end of '{expression}'"); + + if (expression[i] == '"') + { + // Start of a quoted property key + i++; + var start = i; + + while (i < expression.Length) + { + if (expression[i] == '\\') + i += 2; + else if (expression[i] == '"') + break; + else + i++; + } + + if (i < expression.Length && expression[i] == '"') + { + var propertyName = expression.Substring(start, i - start).Replace("\\\"", "\"").Replace("\\\\", "\\"); + parts.Add(new PropertyJsonPathPart(propertyName)); + } + } + else if (expression[i] >= 'a' && expression[i] <= 'z' || + expression[i] >= 'A' && expression[i] <= 'Z') + { + // Start of an unquoted property key + var start = i; + + while (i < expression.Length) + { + if (expression[i] >= 'a' && expression[i] <= 'z' || + expression[i] >= 'A' && expression[i] <= 'Z' || + expression[i] >= '0' && expression[i] <= '9') + { + i++; + } + else + { + break; + } + } + + var propertyName = expression.Substring(start, i - start); + parts.Add(new PropertyJsonPathPart(propertyName)); + + if (i < expression.Length) + i--; + } + else + { + // Error + throw new JsonException($"Invalid JSON path - invalid property name at index {i} of '{expression}'"); + } + } + else if (expression[i] == '[') + { + // Start of an array indexer + var end = expression.IndexOf(']', i); + + if (end == -1) + throw new JsonException($"Invalid JSON path - missing closing bracket for indexer at index {i} of '{expression}'"); + + var indexStr = expression.Substring(i + 1, end - i - 1); + + if (!UInt32.TryParse(indexStr, out var index)) + throw new JsonException($"Invalid JSON path - invalid indexer at index {i} of '{expression}'"); + + parts.Add(new ArrayElementJsonPathPart(index)); + i = end ; + } + else + { + // Error + throw new JsonException($"JSON path is not properly formatted. Unexpected character '{expression[i]}' is found at position {i}"); + } + } + + return parts.ToArray(); + } + + public override string ToString() + { + return _mode.ToString().ToLowerInvariant() + " " + String.Join("", _parts.Select(p => p.ToString())); + } + + /// + /// Represents a single token within the path + /// + abstract class JsonPathPart + { + /// + /// Extracts the required child token from the current context token + /// + /// The current context token + /// The child token that is matched by this part of the path + public abstract JsonElement? Match(JsonElement token); + } + + /// + /// Handles the $ sign representing the context item + /// + class ContextJsonPathPart : JsonPathPart + { + public override JsonElement? Match(JsonElement token) + { + return token; + } + + public override string ToString() + { + return "$"; + } + } + + /// + /// Handles a property (key) name + /// + class PropertyJsonPathPart : JsonPathPart + { + /// + /// Creates a new + /// + /// The key of the property to extract + public PropertyJsonPathPart(string propertyName) + { + PropertyName = propertyName; + } + + /// + /// Returns the key of the property to extract + /// + public string PropertyName { get; } + + public override JsonElement? Match(JsonElement token) + { + if (token.ValueKind != JsonValueKind.Object) + return null; + + foreach (var prop in token.EnumerateObject()) + { + if (prop.NameEquals(PropertyName)) + return prop.Value; + } + + return null; + } + + public override string ToString() + { + if ((PropertyName[0] >= 'a' && PropertyName[0] <= 'z' || PropertyName[0] >= 'A' && PropertyName[0] <= 'Z') + && PropertyName.All(ch => ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')) + return "." + PropertyName; + + return ".\"" + PropertyName.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""; + } + } + + /// + /// Handles an array element indexer + /// + class ArrayElementJsonPathPart : JsonPathPart + { + /// + /// Creates a new + /// + /// The index of the array to extract + public ArrayElementJsonPathPart(uint index) + { + Index = (int)index; + } + + /// + /// The index of the array to extract + /// + public int Index { get; } + + public override JsonElement? Match(JsonElement token) + { + if (token.ValueKind != JsonValueKind.Array || token.GetArrayLength() < Index) + return null; + + return token[Index]; + } + + public override string ToString() + { + return $"[{Index}]"; + } + } + } + + enum JsonPathMode + { + Lax, + Strict + } +} diff --git a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.FetchXml.nuspec b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.FetchXml.nuspec index f02a69da..cddda3d3 100644 --- a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.FetchXml.nuspec +++ b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.FetchXml.nuspec @@ -18,8 +18,10 @@ + + diff --git a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.nuspec b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.nuspec index 21432f0c..f585ab96 100644 --- a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.nuspec +++ b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.nuspec @@ -11,13 +11,31 @@ https://markcarrington.dev/sql4cds-icon/ Convert SQL queries to FetchXml and execute them against Dataverse / D365 Convert SQL queries to FetchXml and execute them against Dataverse / D365 - Fixed use of IN subqueries when data source cannot be converted to FetchXML -Fixed use of LIKE filters with data containing embedded returns -Fixed incorrect row count estimates with joins of huge tables -Fixed left outer join in nested loop when the first record has no matching records from the right source -Fixed use of partitioned aggregates within a loop -Avoid errors when using DEBUG_BYPASS_OPTIMIZATION hint -Avoid using custom paging for IN and EXISTS filters, and where a single child record is guaranteed by the filters + Added Common Table Expression support: +- Non-recursive CTEs are expanded to subqueries for compatibility with TDS Endpoint +- Recurve CTEs are converted to hierarchical FetchXML filters where possible + +Extended JSON support: +- OPENJSON table-valued function +- JSON_QUERY function +- ISJSON function + +Query optimizer improvements: +- Prefer hash joins over merge joins if sorts cannot be folded +- Switch FetchXML sorts to custom sorting after adding joins that require custom paging +- Avoid folding filters to tables in subqueries if the same alias exists in the outer query +- Do not use a left outer join to implement `NOT IN` queries where the subquery uses an inner join + +Added IGNORE_DUP_KEY query hint to ignore duplicate key errors on insert +Added check for multi-currency issues when aggregating non-base currency fields +Clearer progress messages for multi-threaded DML operations + +Fixed use of `UNION` with wildcard columns +Fixed error in nested loop joins with no records from inner source +Fixed use of columns from outer queries in join criteria in subqueries +Fixed time zone mismatch when starting bulk delete jobs +Fixed setting polymorphic lookup fields using TDS Endpoint +Fixed aggregates with very dense data distribution Copyright © 2020 Mark Carrington en-GB @@ -33,8 +51,8 @@ Avoid using custom paging for IN and EXISTS filters, and where a single child re - - + + diff --git a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.projitems b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.projitems index b019dc85..597c12b4 100644 --- a/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.projitems +++ b/MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.projitems @@ -27,11 +27,15 @@ + + + + @@ -119,6 +123,7 @@ + @@ -140,6 +145,8 @@ + + diff --git a/MarkMpn.Sql4Cds.Engine/MetaMetadataCache.cs b/MarkMpn.Sql4Cds.Engine/MetaMetadataCache.cs index 59740d3d..2b6f6a12 100644 --- a/MarkMpn.Sql4Cds.Engine/MetaMetadataCache.cs +++ b/MarkMpn.Sql4Cds.Engine/MetaMetadataCache.cs @@ -92,7 +92,7 @@ static MetaMetadataCache() metadataNode.ManyToOneRelationshipAlias = "relationship_n_1"; metadataNode.ManyToManyRelationshipAlias = "relationship_n_n"; - var metadataSchema = metadataNode.GetSchema(new NodeCompilationContext(null, new StubOptions(), null)); + var metadataSchema = metadataNode.GetSchema(new NodeCompilationContext(null, new StubOptions(), null, null)); _customMetadata["metadata." + metadataNode.EntityAlias] = SchemaToMetadata(metadataSchema, metadataNode.EntityAlias); _customMetadata["metadata." + metadataNode.AttributeAlias] = SchemaToMetadata(metadataSchema, metadataNode.AttributeAlias); @@ -103,7 +103,7 @@ static MetaMetadataCache() var optionsetNode = new GlobalOptionSetQueryNode(); optionsetNode.Alias = "globaloptionset"; - var optionsetSchema = optionsetNode.GetSchema(new NodeCompilationContext(null, new StubOptions(), null)); + var optionsetSchema = optionsetNode.GetSchema(new NodeCompilationContext(null, new StubOptions(), null, null)); _customMetadata["metadata." + optionsetNode.Alias] = SchemaToMetadata(optionsetSchema, optionsetNode.Alias); } diff --git a/MarkMpn.Sql4Cds.Engine/NodeContext.cs b/MarkMpn.Sql4Cds.Engine/NodeContext.cs index 4ded09a4..1ed06b2d 100644 --- a/MarkMpn.Sql4Cds.Engine/NodeContext.cs +++ b/MarkMpn.Sql4Cds.Engine/NodeContext.cs @@ -21,14 +21,17 @@ class NodeCompilationContext /// The data sources that are available to the query /// The options that the query will be executed with /// The names and types of the parameters that are available to the query + /// A callback function to log messages public NodeCompilationContext( IDictionary dataSources, IQueryExecutionOptions options, - IDictionary parameterTypes) + IDictionary parameterTypes, + Action log) { DataSources = dataSources; Options = options; ParameterTypes = parameterTypes; + Log = log ?? (msg => { }); } /// @@ -43,6 +46,7 @@ public NodeCompilationContext( DataSources = parentContext.DataSources; Options = parentContext.Options; ParameterTypes = parameterTypes; + Log = parentContext.Log; _parentContext = parentContext; } @@ -66,6 +70,11 @@ public NodeCompilationContext( /// public DataSource PrimaryDataSource => DataSources[Options.PrimaryDataSource]; + /// + /// A callback function to log messages + /// + public Action Log { get; } + /// /// Generates a unique name for an expression /// @@ -91,12 +100,14 @@ class NodeExecutionContext : NodeCompilationContext /// The options that the query is being executed with /// The names and types of the parameters that are available to the query /// The current value of each parameter + /// A callback function to log messages public NodeExecutionContext( IDictionary dataSources, IQueryExecutionOptions options, IDictionary parameterTypes, - IDictionary parameterValues) - : base(dataSources, options, parameterTypes) + IDictionary parameterValues, + Action log) + : base(dataSources, options, parameterTypes, log) { ParameterValues = parameterValues; } @@ -126,7 +137,7 @@ public ExpressionCompilationContext( IDictionary parameterTypes, INodeSchema schema, INodeSchema nonAggregateSchema) - : base(dataSources, options, parameterTypes) + : base(dataSources, options, parameterTypes, null) { Schema = schema; NonAggregateSchema = nonAggregateSchema; @@ -142,7 +153,7 @@ public ExpressionCompilationContext( NodeCompilationContext nodeContext, INodeSchema schema, INodeSchema nonAggregateSchema) - : base(nodeContext.DataSources, nodeContext.Options, nodeContext.ParameterTypes) + : base(nodeContext.DataSources, nodeContext.Options, nodeContext.ParameterTypes, nodeContext.Log) { Schema = schema; NonAggregateSchema = nonAggregateSchema; @@ -179,8 +190,9 @@ public ExpressionExecutionContext( IQueryExecutionOptions options, IDictionary parameterTypes, IDictionary parameterValues, + Action log, Entity entity) - : base(dataSources, options, parameterTypes, parameterValues) + : base(dataSources, options, parameterTypes, parameterValues, log) { Entity = entity; } @@ -195,7 +207,7 @@ public ExpressionExecutionContext( /// representing each row as it is processed. /// public ExpressionExecutionContext(NodeExecutionContext nodeContext) - : base(nodeContext.DataSources, nodeContext.Options, nodeContext.ParameterTypes, nodeContext.ParameterValues) + : base(nodeContext.DataSources, nodeContext.Options, nodeContext.ParameterTypes, nodeContext.ParameterValues, nodeContext.Log) { Entity = null; } @@ -213,7 +225,7 @@ public ExpressionExecutionContext(NodeExecutionContext nodeContext) /// representing each row as it is processed. /// public ExpressionExecutionContext(ExpressionCompilationContext compilationContext) - : base(compilationContext.DataSources, compilationContext.Options, compilationContext.ParameterTypes, null) + : base(compilationContext.DataSources, compilationContext.Options, compilationContext.ParameterTypes, null, null) { Entity = null; } diff --git a/MarkMpn.Sql4Cds.Engine/TSqlFragmentExtensions.cs b/MarkMpn.Sql4Cds.Engine/TSqlFragmentExtensions.cs index 6116f4ea..8eb6c667 100644 --- a/MarkMpn.Sql4Cds.Engine/TSqlFragmentExtensions.cs +++ b/MarkMpn.Sql4Cds.Engine/TSqlFragmentExtensions.cs @@ -1,7 +1,9 @@ -using Microsoft.SqlServer.TransactSql.ScriptDom; +using MarkMpn.Sql4Cds.Engine.ExecutionPlan; +using Microsoft.SqlServer.TransactSql.ScriptDom; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Linq.Expressions; @@ -31,6 +33,36 @@ public static string ToSql(this TSqlFragment fragment) return sql; } + /// + /// Converts a to the corresponding SQL string in a standardised way + /// + /// The SQL DOM fragment to convert + /// The SQL string that the fragment can be parsed from + public static string ToNormalizedSql(this TSqlFragment fragment) + { + var tokens = new Sql160ScriptGenerator().GenerateTokens(fragment); + + using (var writer = new StringWriter()) + { + foreach (var token in tokens) + { + if (token.TokenType == TSqlTokenType.Identifier) + { + var value = Identifier.DecodeIdentifier(token.Text, out var quoteType); + + if (quoteType != QuoteType.NotQuoted && value.IsValidIdentifier()) + token.Text = value; + } + + writer.Write(token.Text); + } + + writer.Flush(); + + return writer.ToString(); + } + } + /// /// Creates a clone of a /// diff --git a/MarkMpn.Sql4Cds.Engine/TableSizeCache.cs b/MarkMpn.Sql4Cds.Engine/TableSizeCache.cs index 700971c6..f4a9b4dc 100644 --- a/MarkMpn.Sql4Cds.Engine/TableSizeCache.cs +++ b/MarkMpn.Sql4Cds.Engine/TableSizeCache.cs @@ -8,6 +8,11 @@ using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; +#if NETCOREAPP +using Microsoft.PowerPlatform.Dataverse.Client; +#else +using Microsoft.Xrm.Tooling.Connector; +#endif namespace MarkMpn.Sql4Cds.Engine { @@ -24,7 +29,17 @@ public TableSizeCache(IOrganizationService org, IAttributeMetadataCache metadata _org = org; _metadata = metadata; - _version = new Version(((RetrieveVersionResponse)_org.Execute(new RetrieveVersionRequest())).Version); +#if NETCOREAPP + if (org is ServiceClient svc) + _version = svc.ConnectedOrgVersion; + else +#else + if (org is CrmServiceClient svc) + _version = svc.ConnectedOrgVersion; + else +#endif + + _version = new Version(((RetrieveVersionResponse)_org.Execute(new RetrieveVersionRequest())).Version); } private bool UseRetrieveTotalRecordCountRequest => _version.Major >= 9; diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/CteValidatorVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/CteValidatorVisitor.cs new file mode 100644 index 00000000..a022596f --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/Visitors/CteValidatorVisitor.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.SqlServer.TransactSql.ScriptDom; + +namespace MarkMpn.Sql4Cds.Engine.Visitors +{ + /// + /// Checks the properties of a CTE to ensure it is valid + /// + /// + /// https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver16 + /// + class CteValidatorVisitor : TSqlConcreteFragmentVisitor + { + private int _cteReferenceCount; + private FunctionCall _scalarAggregate; + private ScalarSubquery _subquery; + private QualifiedJoin _outerJoin; + + public string Name { get; private set; } + + public bool IsRecursive { get; private set; } + + public QueryExpression AnchorQuery { get; private set; } + + public List RecursiveQueries { get; } = new List(); + + public override void Visit(CommonTableExpression node) + { + Name = node.ExpressionName.Value; + + base.Visit(node); + } + + public override void Visit(FromClause node) + { + _cteReferenceCount = 0; + + base.Visit(node); + + // The FROM clause of a recursive member must refer only one time to the CTE expression_name. + if (_cteReferenceCount > 1) + throw new NotSupportedQueryFragmentException($"Recursive member of a common table expression '{Name}' has multiple recursive references.", node); + } + + public override void Visit(NamedTableReference node) + { + if (node.SchemaObject.Identifiers.Count == 1 && + node.SchemaObject.BaseIdentifier.Value.Equals(Name, StringComparison.OrdinalIgnoreCase)) + { + IsRecursive = true; + _cteReferenceCount++; + + // The following items aren't allowed in the CTE_query_definition of a recursive member: + // A hint applied to a recursive reference to a CTE inside a CTE_query_definition. + if (node.TableHints.Count > 0) + throw new NotSupportedQueryFragmentException($"Hints are not allowed on recursive common table expression (CTE) references. Consider removing hint from recursive CTE reference '{node.SchemaObject.ToSql()}'.", node.TableHints[0]); + } + + base.Visit(node); + } + + public override void Visit(QualifiedJoin node) + { + base.Visit(node); + + if (node.QualifiedJoinType != QualifiedJoinType.Inner) + _outerJoin = node; + } + + public override void ExplicitVisit(BinaryQueryExpression node) + { + base.ExplicitVisit(node); + + if (!IsRecursive) + AnchorQuery = node; + + // UNION ALL is the only set operator allowed between the last anchor member and first recursive member, and when combining multiple recursive members. + if (IsRecursive && (node.BinaryQueryExpressionType != BinaryQueryExpressionType.Union || !node.All)) + throw new NotSupportedQueryFragmentException($"Recursive common table expression '{Name}' does not contain a top-level UNION ALL operator", node); + } + + public override void ExplicitVisit(QueryParenthesisExpression node) + { + base.ExplicitVisit(node); + + if (!IsRecursive) + AnchorQuery = node; + else + RecursiveQueries.Add(node); + } + + public override void ExplicitVisit(QuerySpecification node) + { + _scalarAggregate = null; + _subquery = null; + _outerJoin = null; + + base.ExplicitVisit(node); + + // The following clauses can't be used in the CTE_query_definition: + // ORDER BY (except when a TOP clause is specified) + if (node.OrderByClause != null && node.TopRowFilter == null) + throw new NotSupportedQueryFragmentException("The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified", node.OrderByClause); + + // FOR BROWSE + if (node.ForClause is BrowseForClause) + throw new NotSupportedQueryFragmentException("The FOR BROWSE clause is no longer supported in views", node.ForClause); + + if (IsRecursive) + { + // The following items aren't allowed in the CTE_query_definition of a recursive member: + // SELECT DISTINCT + if (node.UniqueRowFilter == UniqueRowFilter.Distinct) + throw new NotSupportedQueryFragmentException($"DISTINCT operator is not allowed in the recursive part of a recursive common table expression '{Name}'.", node); + + // GROUP BY + if (node.GroupByClause != null) + throw new NotSupportedQueryFragmentException($"GROUP BY, HAVING, or aggregate functions are not allowed in the recursive part of a recursive common table expression '{Name}'", node.GroupByClause); + + // TODO: PIVOT + + // HAVING + if (node.HavingClause != null) + throw new NotSupportedQueryFragmentException($"GROUP BY, HAVING, or aggregate functions are not allowed in the recursive part of a recursive common table expression '{Name}'", node.HavingClause); + + // Scalar aggregation + if (_scalarAggregate != null) + throw new NotSupportedQueryFragmentException($"GROUP BY, HAVING, or aggregate functions are not allowed in the recursive part of a recursive common table expression '{Name}'", _scalarAggregate); + + // TOP + if (node.TopRowFilter != null || node.OffsetClause != null) + throw new NotSupportedQueryFragmentException($"The TOP or OFFSET operator is not allowed in the recursive part of a recursive common table expression '{Name}'", (TSqlFragment)node.TopRowFilter ?? node.OffsetClause); + + // LEFT, RIGHT, OUTER JOIN (INNER JOIN is allowed) + if (_outerJoin != null) + throw new NotSupportedQueryFragmentException($"Outer join is not allowed in the recursive part of a recursive common table expression '{Name}'", _outerJoin); + + // Subqueries + if (_subquery != null) + throw new NotSupportedQueryFragmentException("Recursive references are not allowed in subqueries", _subquery); + } + + if (!IsRecursive) + AnchorQuery = node; + else + RecursiveQueries.Add(node); + } + + public override void Visit(SelectStatement node) + { + base.Visit(node); + + // The following clauses can't be used in the CTE_query_definition: + // INTO + if (node.Into != null) + throw new NotSupportedQueryFragmentException("INTO is not supported in CTEs", node.Into); + + // OPTION clause with query hints + if (node.OptimizerHints.Count > 0) + throw new NotSupportedQueryFragmentException("Optimizer hints are not supported in CTEs", node.OptimizerHints[0]); + } + + public override void ExplicitVisit(ScalarSubquery node) + { + var count = _cteReferenceCount; + + base.ExplicitVisit(node); + + if (_cteReferenceCount > count) + _subquery = node; + } + + public override void Visit(FunctionCall node) + { + base.Visit(node); + + switch (node.FunctionName.Value.ToLowerInvariant()) + { + case "approx_count_distinct": + case "avg": + case "checksum_agg": + case "count": + case "count_big": + case "grouping": + case "grouping_id": + case "max": + case "min": + case "stdev": + case "stdevp": + case "string_agg": + case "sum": + case "var": + case "varp": + _scalarAggregate = node; + break; + } + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/OptimizerHintValidatingVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/OptimizerHintValidatingVisitor.cs index 7645421a..a27698ac 100644 --- a/MarkMpn.Sql4Cds.Engine/Visitors/OptimizerHintValidatingVisitor.cs +++ b/MarkMpn.Sql4Cds.Engine/Visitors/OptimizerHintValidatingVisitor.cs @@ -57,6 +57,9 @@ class OptimizerHintValidatingVisitor : TSqlFragmentVisitor // Custom hint to use legacy specialized update messages - https://learn.microsoft.com/en-us/power-apps/developer/data-platform/org-service/entity-operations-update-delete?tabs=late#legacy-update-messages "USE_LEGACY_UPDATE_MESSAGES", + + // Ignore duplicate keys on insert, equivalent to IGNORE_DUP_KEY option on creation of index + "IGNORE_DUP_KEY", }; private static readonly HashSet _removableSql4CdsQueryHints = new HashSet(StringComparer.OrdinalIgnoreCase) diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/RemoveRecursiveCTETableReferencesVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/RemoveRecursiveCTETableReferencesVisitor.cs new file mode 100644 index 00000000..f197efff --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/Visitors/RemoveRecursiveCTETableReferencesVisitor.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using MarkMpn.Sql4Cds.Engine.ExecutionPlan; +using Microsoft.SqlServer.TransactSql.ScriptDom; + +namespace MarkMpn.Sql4Cds.Engine.Visitors +{ + /// + /// Finds recursive references in a CTE definition and removes them, moving join predicates to the WHERE clause + /// + class RemoveRecursiveCTETableReferencesVisitor : TSqlConcreteFragmentVisitor + { + private string _name; + private readonly string[] _columnNames; + private readonly Dictionary _outerReferences; + private BooleanExpression _joinPredicate; + private int _inUnqualifiedJoin; + private bool _usingInlineDerivedTable; + + public RemoveRecursiveCTETableReferencesVisitor(string name, string[] columnNames, Dictionary outerReferences) + { + _name = name; + _columnNames = columnNames; + _outerReferences = outerReferences; + } + + private bool IsRecursiveReference(TableReference tableReference) + { + if (!(tableReference is NamedTableReference namedTable)) + return false; + + if (namedTable.SchemaObject.Identifiers.Count != 1) + return false; + + if (!namedTable.SchemaObject.BaseIdentifier.Value.Equals(_name, StringComparison.OrdinalIgnoreCase)) + return false; + + if (namedTable.Alias != null) + _name = namedTable.Alias.Value; + + return true; + } + + private InlineDerivedTable CreateInlineDerivedTable() + { + _usingInlineDerivedTable = true; + + var table = new InlineDerivedTable + { + Alias = new Identifier { Value = _name }, + RowValues = { new RowValue() } + }; + + foreach (var col in _columnNames) + { + table.Columns.Add(new Identifier { Value = col }); + table.RowValues[0].ColumnValues.Add(new VariableReference { Name = _outerReferences[col] }); + } + + return table; + } + + private bool RemoveRecursiveJoin(TableReference tableReference, out TableReference removed) + { + removed = null; + + if (!(tableReference is JoinTableReference join)) + return false; + + if (IsRecursiveReference(join.FirstTableReference)) + { + if (_inUnqualifiedJoin > 0) + { + join.FirstTableReference = CreateInlineDerivedTable(); + return false; + } + + _joinPredicate = (join as QualifiedJoin)?.SearchCondition; + removed = join.SecondTableReference; + return true; + } + + if (IsRecursiveReference(join.SecondTableReference)) + { + if (_inUnqualifiedJoin > 0) + { + join.SecondTableReference = CreateInlineDerivedTable(); + return false; + } + + _joinPredicate = (join as QualifiedJoin)?.SearchCondition; + removed = join.FirstTableReference; + return true; + } + + return false; + } + + public override void Visit(FromClause node) + { + base.Visit(node); + + for (var i = 0; i < node.TableReferences.Count; i++) + { + if (IsRecursiveReference(node.TableReferences[i])) + { + if (_inUnqualifiedJoin > 0) + node.TableReferences[i] = CreateInlineDerivedTable(); + else + node.TableReferences.RemoveAt(i); + } + else if (RemoveRecursiveJoin(node.TableReferences[i], out var removed)) + { + node.TableReferences[i] = removed; + } + } + } + + public override void Visit(QualifiedJoin node) + { + base.Visit(node); + + if (RemoveRecursiveJoin(node.FirstTableReference, out var removed)) + node.FirstTableReference = removed; + + if (RemoveRecursiveJoin(node.SecondTableReference, out removed)) + node.SecondTableReference = removed; + } + + public override void Visit(UnqualifiedJoin node) + { + base.Visit(node); + + if (RemoveRecursiveJoin(node.FirstTableReference, out var removed)) + node.FirstTableReference = removed; + } + + public override void ExplicitVisit(UnqualifiedJoin node) + { + node.FirstTableReference.Accept(this); + + _inUnqualifiedJoin++; + + if (RemoveRecursiveJoin(node.SecondTableReference, out var removed)) + node.SecondTableReference = removed; + + node.SecondTableReference.Accept(this); + _inUnqualifiedJoin--; + } + + public override void ExplicitVisit(QuerySpecification node) + { + base.ExplicitVisit(node); + + if (_joinPredicate != null) + { + if (node.WhereClause == null) + { + node.WhereClause = new WhereClause { SearchCondition = _joinPredicate }; + } + else + { + node.WhereClause.SearchCondition = new BooleanBinaryExpression + { + FirstExpression = node.WhereClause.SearchCondition, + BinaryExpressionType = BooleanBinaryExpressionType.And, + SecondExpression = _joinPredicate + }; + } + } + + if (!_usingInlineDerivedTable) + { + // Replace references to the recursive CTE columns with variables + var rewrites = _outerReferences + .SelectMany(kvp => new[] { kvp, new KeyValuePair(_name.EscapeIdentifier() + "." + kvp.Key, kvp.Value) }) + .ToDictionary(kvp => (ScalarExpression)kvp.Key.ToColumnReference(), kvp => (ScalarExpression)new VariableReference { Name = kvp.Value }); + + node.Accept(new RewriteVisitor(rewrites)); + } + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/ReplaceCtesWithSubqueriesVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/ReplaceCtesWithSubqueriesVisitor.cs new file mode 100644 index 00000000..ff55c91c --- /dev/null +++ b/MarkMpn.Sql4Cds.Engine/Visitors/ReplaceCtesWithSubqueriesVisitor.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.SqlServer.TransactSql.ScriptDom; + +namespace MarkMpn.Sql4Cds.Engine.Visitors +{ + /// + /// Finds references to non-recursive CTEs and replaces them with subqueries + /// + class ReplaceCtesWithSubqueriesVisitor : TSqlFragmentVisitor + { + private Dictionary _cteQueries; + + public ReplaceCtesWithSubqueriesVisitor() + { + _cteQueries = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + public override void Visit(CommonTableExpression node) + { + base.Visit(node); + + _cteQueries[node.ExpressionName.Value] = node; + } + + public override void Visit(SelectStatement node) + { + // Visit the CTEs first + if (node.WithCtesAndXmlNamespaces != null) + node.WithCtesAndXmlNamespaces.Accept(this); + + base.Visit(node); + + // Should have visited the CTEs now, so remove them from the query + node.WithCtesAndXmlNamespaces = null; + } + + public override void Visit(FromClause node) + { + base.Visit(node); + + for (var i = 0; i < node.TableReferences.Count; i++) + { + if (node.TableReferences[i] is NamedTableReference ntr && + TryGetCteDefinition(ntr, out var subquery)) + { + node.TableReferences[i] = subquery; + } + } + } + + public override void Visit(QualifiedJoin node) + { + base.Visit(node); + + if (node.FirstTableReference is NamedTableReference table1 && + TryGetCteDefinition(table1, out var subquery1)) + { + node.FirstTableReference = subquery1; + } + + if (node.SecondTableReference is NamedTableReference table2 && + TryGetCteDefinition(table2, out var subquery2)) + { + node.SecondTableReference = subquery2; + } + } + + public override void Visit(UnqualifiedJoin node) + { + base.Visit(node); + + if (node.FirstTableReference is NamedTableReference table1 && + TryGetCteDefinition(table1, out var subquery1)) + { + node.FirstTableReference = subquery1; + } + + if (node.SecondTableReference is NamedTableReference table2 && + TryGetCteDefinition(table2, out var subquery2)) + { + node.SecondTableReference = subquery2; + } + } + + private bool TryGetCteDefinition(NamedTableReference table, out QueryDerivedTable subquery) + { + subquery = null; + + if (table.SchemaObject.Identifiers.Count > 1) + return false; + + if (!_cteQueries.TryGetValue(table.SchemaObject.BaseIdentifier.Value, out var cte)) + return false; + + subquery = new QueryDerivedTable + { + Alias = table.Alias ?? cte.ExpressionName, + QueryExpression = cte.QueryExpression + }; + + foreach (var col in cte.Columns) + subquery.Columns.Add(col); + + return true; + } + } +} diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitor.cs index 90f77f43..d66b521d 100644 --- a/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitor.cs +++ b/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitor.cs @@ -27,7 +27,7 @@ class RewriteVisitor : RewriteVisitorBase public RewriteVisitor(IDictionary rewrites) { _mappings = rewrites - .GroupBy(kvp => kvp.Key.ToSql(), StringComparer.OrdinalIgnoreCase) + .GroupBy(kvp => kvp.Key.ToNormalizedSql(), StringComparer.OrdinalIgnoreCase) .ToDictionary( g => g.Key, g => (ScalarExpression) g.First().Value.ToColumnReference(), @@ -37,7 +37,7 @@ public RewriteVisitor(IDictionary rewrites) public RewriteVisitor(IDictionary rewrites) { _mappings = rewrites - .GroupBy(kvp => kvp.Key.ToSql(), StringComparer.OrdinalIgnoreCase) + .GroupBy(kvp => kvp.Key.ToNormalizedSql(), StringComparer.OrdinalIgnoreCase) .ToDictionary( g => g.Key, g => g.First().Value, @@ -51,7 +51,7 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio if (expression == null) return null; - if (_mappings.TryGetValue(expression.ToSql(), out var column)) + if (_mappings.TryGetValue(expression.ToNormalizedSql(), out var column)) { name = (column as ColumnReferenceExpression)?.MultiPartIdentifier?.Identifiers?.Last()?.Value; return column; diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitorBase.cs b/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitorBase.cs index b1990b2d..c0259916 100644 --- a/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitorBase.cs +++ b/MarkMpn.Sql4Cds.Engine/Visitors/RewriteVisitorBase.cs @@ -227,5 +227,12 @@ public override void ExplicitVisit(SchemaObjectFunctionTableReference node) } } } + + public override void ExplicitVisit(OpenJsonTableReference node) + { + base.ExplicitVisit(node); + ReplaceExpression(node, n => n.Variable); + ReplaceExpression(node, n => n.RowPattern); + } } } diff --git a/MarkMpn.Sql4Cds.Engine/Visitors/TDSEndpointCompatibilityVisitor.cs b/MarkMpn.Sql4Cds.Engine/Visitors/TDSEndpointCompatibilityVisitor.cs index 3f50260c..96b29cfe 100644 --- a/MarkMpn.Sql4Cds.Engine/Visitors/TDSEndpointCompatibilityVisitor.cs +++ b/MarkMpn.Sql4Cds.Engine/Visitors/TDSEndpointCompatibilityVisitor.cs @@ -19,6 +19,7 @@ class TDSEndpointCompatibilityVisitor : TSqlFragmentVisitor private readonly IAttributeMetadataCache _metadata; private readonly Dictionary _tableNames; private readonly HashSet _supportedTables; + private readonly Dictionary _ctes; private bool? _isEntireBatch; private TSqlFragment _root; @@ -30,11 +31,13 @@ class TDSEndpointCompatibilityVisitor : TSqlFragmentVisitor /// Indicates if this query is the entire SQL batch, or a single statement within it /// A mapping of table aliases to table names available from the outer query /// A pre-calculated list of supported tables - public TDSEndpointCompatibilityVisitor(IDbConnection con, IAttributeMetadataCache metadata, bool? isEntireBatch = null, Dictionary outerTableNames = null, HashSet supportedTables = null) + /// A mapping of CTE names to their definitions from the outer query + public TDSEndpointCompatibilityVisitor(IDbConnection con, IAttributeMetadataCache metadata, bool? isEntireBatch = null, Dictionary outerTableNames = null, HashSet supportedTables = null, Dictionary ctes = null) { _con = con; _metadata = metadata; _tableNames = new Dictionary(StringComparer.OrdinalIgnoreCase); + _ctes = ctes ?? new Dictionary(StringComparer.OrdinalIgnoreCase); _isEntireBatch = isEntireBatch; if (outerTableNames != null) @@ -68,6 +71,8 @@ public TDSEndpointCompatibilityVisitor(IDbConnection con, IAttributeMetadataCach public bool IsCompatible { get; private set; } + public bool RequiresCteRewrite { get; private set; } + public override void Visit(TSqlFragment node) { if (_root == null) @@ -93,9 +98,10 @@ public override void Visit(NamedTableReference node) return; } - if (_supportedTables != null && !_supportedTables.Contains(node.SchemaObject.BaseIdentifier.Value)) + if (_supportedTables != null && !_supportedTables.Contains(node.SchemaObject.BaseIdentifier.Value) && + (node.SchemaObject.Identifiers.Count != 1 || !_ctes.ContainsKey(node.SchemaObject.BaseIdentifier.Value))) { - // Table does not exist in TDS endpoint + // Table does not exist in TDS endpoint and is not defined as a CTE IsCompatible = false; return; } @@ -121,15 +127,26 @@ public override void Visit(ColumnReferenceExpression node) // Table name not specified. Try to find it in the list of current tables foreach (var table in _tableNames.Values) { - var attribute = TryGetEntity(table)?.Attributes?.SingleOrDefault(a => a.LogicalName.Equals(columnName)); - - if (!AttributeIsSupported(attribute)) + if (!GetCTECols(table, out _)) { - IsCompatible = false; - return; + var attribute = TryGetEntity(table)?.Attributes?.SingleOrDefault(a => a.LogicalName.Equals(columnName)); + + if (!AttributeIsSupported(attribute)) + { + IsCompatible = false; + return; + } } } } + else if (GetCTECols(node.MultiPartIdentifier[0].Value, out var cols)) + { + if (!cols.Contains(columnName)) + { + IsCompatible = false; + return; + } + } else { var attribute = TryGetEntity(node.MultiPartIdentifier[0].Value)?.Attributes?.SingleOrDefault(a => a.LogicalName.Equals(columnName)); @@ -145,6 +162,51 @@ public override void Visit(ColumnReferenceExpression node) base.Visit(node); } + private bool GetCTECols(string cteName, out HashSet cols) + { + cols = null; + + if (!_ctes.TryGetValue(cteName, out var cte)) + return false; + + cols = new HashSet(StringComparer.OrdinalIgnoreCase); + + if (cte.Columns.Count > 0) + { + foreach (var col in cte.Columns) + cols.Add(col.Value); + } + else + { + var query = cte.QueryExpression; + + while (query is BinaryQueryExpression bin) + query = bin.FirstQueryExpression; + + if (!(query is QuerySpecification spec)) + return false; + + // Can't easily work out the column names that will be produced by a SELECT * within a CTE + if (spec.SelectElements.OfType().Any()) + return false; + + foreach (var col in spec.SelectElements.OfType()) + { + if (!(col is SelectScalarExpression sse)) + return false; + + if (sse.ColumnName != null) + cols.Add(sse.ColumnName.Value); + else if (sse.Expression is ColumnReferenceExpression cre) + cols.Add(cre.MultiPartIdentifier.Identifiers.Last().Value); + else + return false; + } + } + + return true; + } + private EntityMetadata TryGetEntity(string logicalname) { if (!IsCompatible) @@ -227,12 +289,15 @@ public override void Visit(ScalarSubquery node) // Name resolution needs to be scoped to the query, so create a new sub-visitor if (IsCompatible && _root != node) { - var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, _tableNames, _supportedTables); + var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, _tableNames, _supportedTables, _ctes); node.Accept(subVisitor); if (!subVisitor.IsCompatible) IsCompatible = false; + if (subVisitor.RequiresCteRewrite) + RequiresCteRewrite = true; + return; } @@ -244,33 +309,45 @@ public override void Visit(QueryDerivedTable node) // Name resolution needs to be scoped to the query, so create a new sub-visitor if (IsCompatible && _root != node) { - var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, supportedTables: _supportedTables); + var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, supportedTables: _supportedTables, ctes: _ctes); node.Accept(subVisitor); if (!subVisitor.IsCompatible) IsCompatible = false; + if (subVisitor.RequiresCteRewrite) + RequiresCteRewrite = true; + return; } base.Visit(node); } - public override void Visit(SelectStatement node) + public override void ExplicitVisit(SelectStatement node) { // Name resolution needs to be scoped to the query, so create a new sub-visitor if (IsCompatible && _root != node) { - var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, supportedTables: _supportedTables); + var subVisitor = new TDSEndpointCompatibilityVisitor(_con, _metadata, _isEntireBatch, supportedTables: _supportedTables, ctes: _ctes); + subVisitor._root = node; + + // Visit CTEs first + if (node.WithCtesAndXmlNamespaces != null) + node.WithCtesAndXmlNamespaces.Accept(subVisitor); + node.Accept(subVisitor); if (!subVisitor.IsCompatible) IsCompatible = false; + if (subVisitor.RequiresCteRewrite) + RequiresCteRewrite = true; + return; } - base.Visit(node); + base.ExplicitVisit(node); } public override void Visit(QuerySpecification node) @@ -321,5 +398,23 @@ public override void Visit(DistinctPredicate node) // Can't use IS [NOT] DISTINCT FROM IsCompatible = false; } + + public override void Visit(CommonTableExpression node) + { + var cteValidator = new CteValidatorVisitor(); + node.Accept(cteValidator); + + if (cteValidator.IsRecursive) + { + IsCompatible = false; + } + else + { + // TDS Endpoint doesn't support CTEs but we can rewrite non-recursive ones as subqueries + RequiresCteRewrite = true; + } + + _ctes[node.ExpressionName.Value] = node; + } } } diff --git a/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/Autocomplete.cs b/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/Autocomplete.cs index 76253508..e322d61c 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/Autocomplete.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/Autocomplete.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Text; +using Data8.PowerPlatform.Dataverse.Client.Wsdl; using MarkMpn.Sql4Cds.Engine; using Microsoft.Crm.Sdk.Messages; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -568,13 +569,15 @@ public IEnumerable GetSuggestions(string text, int pos) { // Check if there are any applicable filter operator functions that match the type of the current attribute var identifiers = prevPrevWord.Split('.'); + var instance = default(AutocompleteDataSource); + var entity = default(EntityMetadata); var attribute = default(AttributeMetadata); if (identifiers.Length == 2) { if (tables.TryGetValue(identifiers[0], out var tableName)) { - if (TryParseTableName(tableName, out var instanceName, out _, out tableName) && _dataSources.TryGetValue(instanceName, out var instance) && instance.Metadata.TryGetMinimalData(tableName, out var entity)) + if (TryParseTableName(tableName, out var instanceName, out _, out tableName) && _dataSources.TryGetValue(instanceName, out instance) && instance.Metadata.TryGetMinimalData(tableName, out entity)) { attribute = entity.Attributes.SingleOrDefault(a => a.LogicalName.Equals(identifiers[1], StringComparison.OrdinalIgnoreCase)); } @@ -584,7 +587,7 @@ public IEnumerable GetSuggestions(string text, int pos) { foreach (var table in tables.Values) { - if (TryParseTableName(table, out var instanceName, out _, out var tableName) && _dataSources.TryGetValue(instanceName, out var instance) && instance.Metadata.TryGetMinimalData(tableName, out var entity)) + if (TryParseTableName(table, out var instanceName, out _, out var tableName) && _dataSources.TryGetValue(instanceName, out instance) && instance.Metadata.TryGetMinimalData(tableName, out entity)) { var tableAttribute = entity.Attributes.SingleOrDefault(a => a.LogicalName.Equals(identifiers[0], StringComparison.OrdinalIgnoreCase)); @@ -623,8 +626,25 @@ public IEnumerable GetSuggestions(string text, int pos) items.AddRange(typeof(FetchXmlConditionMethods).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.GetParameters()[0].ParameterType == expectedType).Select(m => new FunctionAutocompleteItem(m, currentLength))); } - if (attribute is EnumAttributeMetadata enumAttr) + if (attribute is EntityNameAttributeMetadata entityNameAttr) + { + var lookupAttr = entity.Attributes.SingleOrDefault(a => a.LogicalName == entityNameAttr.AttributeOf) as LookupAttributeMetadata; + + if (lookupAttr?.Targets == null || lookupAttr.Targets.Length == 0) + { + // Could be any entity name, show them all + items.AddRange(instance.Entities.Select(e => new EntityNameAutocompleteItem(e, currentLength))); + } + else + { + // Can only be one of the allowed entity types + items.AddRange(instance.Entities.Where(e => lookupAttr.Targets.Contains(e.LogicalName)).Select(e => new EntityNameAutocompleteItem(e, currentLength))); + } + } + else if (attribute is EnumAttributeMetadata enumAttr) + { items.AddRange(enumAttr.OptionSet.Options.Select(o => new OptionSetAutocompleteItem(o, currentLength))); + } } } @@ -1800,6 +1820,33 @@ public override string ToolTipText } } + class EntityNameAutocompleteItem : SqlAutocompleteItem + { + private readonly EntityMetadata _entity; + + public EntityNameAutocompleteItem(EntityMetadata entity, int replaceLength) : base(entity.LogicalName, replaceLength, CompletionItemKind.Text) + { + _entity = entity; + } + + public override string ToolTipTitle + { + get => _entity.DisplayName?.UserLocalizedLabel?.Label ?? _entity.LogicalName; + set => base.ToolTipTitle = value; + } + + public override string ToolTipText + { + get => _entity.Description?.UserLocalizedLabel?.Label; + set => base.ToolTipText = value; + } + + public override string GetTextForReplace() + { + return "'" + _entity.LogicalName + "'"; + } + } + class CollationAutocompleteItem : SqlAutocompleteItem { private readonly Collation _collation; diff --git a/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/FunctionMetadata.cs b/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/FunctionMetadata.cs index 100893a4..b6523c58 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/FunctionMetadata.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/Autocomplete/FunctionMetadata.cs @@ -58,6 +58,12 @@ public abstract class SqlFunctions [Description("Extracts a scalar value from a JSON string")] public abstract string json_value(string json, string path); + [Description("Extracts an object or an array from a JSON string")] + public abstract string json_query(string json, string path); + + [Description("Tests whether a string contains valid JSON")] + public abstract string isjson(string json, string type); + [Description("Tests whether a specified SQL/JSON path exists in the input JSON string")] public abstract bool json_path_exists(string json, string path); diff --git a/MarkMpn.Sql4Cds.LanguageServer/Capabilities/CapabilitiesHandler.cs b/MarkMpn.Sql4Cds.LanguageServer/Capabilities/CapabilitiesHandler.cs index a627417d..e09d26c1 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/Capabilities/CapabilitiesHandler.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/Capabilities/CapabilitiesHandler.cs @@ -84,7 +84,7 @@ public CapabilitiesResult HandleCapabilities(CapabilitiesRequest request) _ = _lsp.NotifyAsync(Methods.WindowLogMessage, new LogMessageParams { MessageType = MessageType.Warning, - Message = $"Update to v{result.Result.ToString(3)} available from https://markcarrington.dev/sql-4-cds/" + Message = $"Update to v{result.Result.ToString(3)} available from https://github.com/MarkMpn/Sql4Cds/releases/download/v{result.Result.ToString(3)}/azuredatastudio-sql4cds-{result.Result.ToString(3)}.vsix" }); } }, TaskScheduler.Default); diff --git a/MarkMpn.Sql4Cds.LanguageServer/Connection/ConnectionManager.cs b/MarkMpn.Sql4Cds.LanguageServer/Connection/ConnectionManager.cs index 33c01857..45dd83b6 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/Connection/ConnectionManager.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/Connection/ConnectionManager.cs @@ -49,7 +49,10 @@ public Session Connect(ConnectionDetails connection, string ownerUri) public void Disconnect(string ownerUri) { - _connectedDataSource.TryRemove(ownerUri, out _); + if (_connectedDataSource.TryRemove(ownerUri, out var dataSourceName) && + !_connectedDataSource.Any(kvp => kvp.Value == dataSourceName)) + _dataSources.TryRemove(dataSourceName, out _); + _connections.TryRemove(ownerUri, out _); } diff --git a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionParams.cs b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionParams.cs new file mode 100644 index 00000000..611cb280 --- /dev/null +++ b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionParams.cs @@ -0,0 +1,14 @@ +namespace MarkMpn.Sql4Cds.LanguageServer.ObjectExplorer.Contracts +{ + /// + /// Parameters to the . + /// + public class CloseSessionParams + { + /// + /// The Id returned from a . This + /// is used to disambiguate between different trees. + /// + public string SessionId { get; set; } + } +} diff --git a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionRequest.cs b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionRequest.cs new file mode 100644 index 00000000..cbdea1ed --- /dev/null +++ b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionRequest.cs @@ -0,0 +1,15 @@ +using MarkMpn.Sql4Cds.LanguageServer.Connection.Contracts; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace MarkMpn.Sql4Cds.LanguageServer.ObjectExplorer.Contracts +{ + /// + /// Closes an Object Explorer tree session for a specific connection. + /// + public class CloseSessionRequest + { + public const string MessageName = "objectexplorer/closesession"; + + public static readonly LspRequest Type = new LspRequest(MessageName); + } +} diff --git a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionResponse.cs b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionResponse.cs new file mode 100644 index 00000000..2464e72c --- /dev/null +++ b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/CloseSessionResponse.cs @@ -0,0 +1,21 @@ +namespace MarkMpn.Sql4Cds.LanguageServer.ObjectExplorer.Contracts +{ + /// + /// Information returned from a . + /// Contains success information, a to be used when + /// requesting closing an existing session. + /// + public class CloseSessionResponse + { + /// + /// Boolean indicating if the session was closed successfully + /// + public bool Success { get; set; } + + /// + /// Unique ID to use when sending any requests for objects in the + /// tree under the node + /// + public string SessionId { get; set; } + } +} diff --git a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/SessionDisconnectedNotification.cs b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/SessionDisconnectedNotification.cs new file mode 100644 index 00000000..d1ba63e0 --- /dev/null +++ b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/Contracts/SessionDisconnectedNotification.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace MarkMpn.Sql4Cds.LanguageServer.ObjectExplorer.Contracts +{ + /// + /// Information returned when a session is disconnected. + /// Contains success information and a + /// + public class SessionDisconnectedParameters + { + /// + /// Boolean indicating if the connection was successful + /// + public bool Success { get; set; } + + /// + /// Unique ID to use when sending any requests for objects in the + /// tree under the node + /// + public string SessionId { get; set; } + + /// + /// Error message returned from the engine for a object explorer session failure reason, if any. + /// + public string ErrorMessage { get; set; } + } + + /// + /// Session disconnected notification + /// + public class SessionDisconnectedNotification + { + public const string MessageName = "objectexplorer/sessiondisconnected"; + + public static readonly LspNotification Type = new LspNotification(MessageName); + } +} diff --git a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/ObjectExplorerHandler.cs b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/ObjectExplorerHandler.cs index e3ef7c42..d27b8067 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/ObjectExplorerHandler.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/ObjectExplorer/ObjectExplorerHandler.cs @@ -29,6 +29,7 @@ public void Initialize(JsonRpc lsp) lsp.AddHandler(CreateSessionRequest.Type, HandleCreateSession); lsp.AddHandler(ExpandRequest.Type, HandleExpand); lsp.AddHandler(RefreshRequest.Type, HandleRefresh); + lsp.AddHandler(CloseSessionRequest.Type, HandleCloseSession); } public CreateSessionResponse HandleCreateSession(ConnectionDetails request) @@ -61,6 +62,24 @@ public CreateSessionResponse HandleCreateSession(ConnectionDetails request) return new CreateSessionResponse { SessionId = session.SessionId }; } + public CloseSessionResponse HandleCloseSession(CloseSessionParams request) + { + _connectionManager.Disconnect(request.SessionId); + + _ = _lsp.NotifyAsync(SessionDisconnectedNotification.Type, new SessionDisconnectedParameters + { + SessionId = request.SessionId, + Success = true, + ErrorMessage = null + }); + + return new CloseSessionResponse + { + SessionId = request.SessionId, + Success = true + }; + } + public bool HandleExpand(ExpandParams request) { var session = _connectionManager.GetConnection(request.SessionId); diff --git a/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/Contracts/ConfirmationResponse.cs b/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/Contracts/ConfirmationResponse.cs index bd2793da..ef66e37a 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/Contracts/ConfirmationResponse.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/Contracts/ConfirmationResponse.cs @@ -6,7 +6,14 @@ public class ConfirmationResponseParams { public string OwnerUri { get; set; } - public bool Result { get; set; } + public ConfirmationResult Result { get; set; } + } + + public enum ConfirmationResult + { + No, + Yes, + All } public class ConfirmationResponse diff --git a/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/QueryExecutionHandler.cs b/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/QueryExecutionHandler.cs index 5d2abdaa..2e0ab3c0 100644 --- a/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/QueryExecutionHandler.cs +++ b/MarkMpn.Sql4Cds.LanguageServer/QueryExecution/QueryExecutionHandler.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Net; +using System.ServiceModel; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -18,11 +19,9 @@ using MarkMpn.Sql4Cds.LanguageServer.Workspace; using Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts; using Microsoft.VisualStudio.LanguageServer.Protocol; +using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Metadata; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using StreamJsonRpc; -using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; namespace MarkMpn.Sql4Cds.LanguageServer.QueryExecution { @@ -34,7 +33,7 @@ class QueryExecutionHandler : IJsonRpcMethodHandler private readonly ConcurrentDictionary> _resultSets; private readonly ConcurrentDictionary _commands; private readonly ConcurrentDictionary _confirmationEvents; - private readonly ConcurrentDictionary _confirmationResults; + private readonly ConcurrentDictionary _confirmationResults; public QueryExecutionHandler(JsonRpc lsp, ConnectionManager connectionManager, TextDocumentManager documentManager) { @@ -44,7 +43,7 @@ public QueryExecutionHandler(JsonRpc lsp, ConnectionManager connectionManager, T _resultSets = new ConcurrentDictionary>(); _commands = new ConcurrentDictionary(); _confirmationEvents = new ConcurrentDictionary(); - _confirmationResults = new ConcurrentDictionary(); + _confirmationResults = new ConcurrentDictionary(); } public void Initialize(JsonRpc lsp) @@ -101,7 +100,7 @@ public ExecuteRequestResult HandleExecuteDocumentSelection(ExecuteDocumentSelect qry += '\n'; } - await Execute(session, request, qry, request.QuerySelection); + await ExecuteAsync(session, request, qry, request.QuerySelection); }); return new ExecuteRequestResult(); @@ -124,13 +123,13 @@ private ExecuteRequestResult HandleExecuteString(ExecuteStringParams request) _ = Task.Run(async () => { var lines = request.Query.Split('\n'); - await Execute(session, request, request.Query, new SelectionData { StartLine =0, StartColumn = 0, EndLine = lines.Length - 1, EndColumn = lines[lines.Length - 1].Length }); + await ExecuteAsync(session, request, request.Query, new SelectionData { StartLine =0, StartColumn = 0, EndLine = lines.Length - 1, EndColumn = lines[lines.Length - 1].Length }); }); return new ExecuteRequestResult(); } - private async Task Execute(Connection.Session session, ExecuteRequestParamsBase request, string qry, SelectionData selection) + private async Task ExecuteAsync(Connection.Session session, ExecuteRequestParamsBase request, string qry, SelectionData selection) { // query/batchStart (BatchEventParams) // query/message (MessagePArams) @@ -140,6 +139,7 @@ private async Task Execute(Connection.Session session, ExecuteRequestParamsBase // query/batchComplete (BatchEventParams) var startTime = DateTime.UtcNow; ResultSetSummary resultSetInProgress = null; + var bypassWarnings = false; var batchSummary = new BatchSummary { @@ -192,7 +192,7 @@ private async Task Execute(Connection.Session session, ExecuteRequestParamsBase { e.Cancel = false; - if (e.Count > threshold || e.BypassCustomPluginExecution) + if ((e.Count > threshold || e.BypassCustomPluginExecution) && !bypassWarnings) { var msg = $"{operation} will affect {e.Count:N0} {GetDisplayName(e.Count, e.Metadata)}."; if (e.BypassCustomPluginExecution) @@ -203,7 +203,8 @@ private async Task Execute(Connection.Session session, ExecuteRequestParamsBase _confirmationEvents[request.OwnerUri] = evt; _ = _lsp.NotifyAsync(ConfirmationRequest.Type, new ConfirmationParams { OwnerUri = request.OwnerUri, Msg = msg }); evt.Wait(); - e.Cancel = !_confirmationResults[request.OwnerUri]; + e.Cancel = _confirmationResults[request.OwnerUri] == ConfirmationResult.No; + bypassWarnings = _confirmationResults[request.OwnerUri] == ConfirmationResult.All; _confirmationEvents.Remove(request.OwnerUri, out _); _confirmationResults.Remove(request.OwnerUri, out _); }; @@ -400,7 +401,7 @@ private async Task Execute(Connection.Session session, ExecuteRequestParamsBase { BatchId = batchSummary.Id, Time = DateTime.UtcNow.ToString("o"), - Message = ex.Message, + Message = GetErrorMessage(ex), IsError = true } }); @@ -507,6 +508,54 @@ private async Task Execute(Connection.Session session, ExecuteRequestParamsBase }); } + private string GetErrorMessage(Exception error) + { + string msg; + + if (error is AggregateException aggregateException) + msg = String.Join("\r\n", aggregateException.InnerExceptions.Select(ex => GetErrorMessage(ex))); + else + msg = error.Message; + + while (error.InnerException != null) + { + if (error.InnerException.Message != error.Message) + msg += "\r\n" + error.InnerException.Message; + + error = error.InnerException; + } + + if (error is FaultException faultEx) + { + var fault = faultEx.Detail; + + if (fault.Message != error.Message) + msg += "\r\n" + fault.Message; + + if (fault.ErrorDetails.TryGetValue("Plugin.ExceptionFromPluginExecute", out var plugin)) + msg += "\r\nError from plugin: " + plugin; + + if (!String.IsNullOrEmpty(fault.TraceText)) + msg += "\r\nTrace log: " + fault.TraceText; + + while (fault.InnerFault != null) + { + if (fault.InnerFault.Message != fault.Message) + msg += "\r\n" + fault.InnerFault.Message; + + fault = fault.InnerFault; + + if (fault.ErrorDetails.TryGetValue("Plugin.ExceptionFromPluginExecute", out plugin)) + msg += "\r\nError from plugin: " + plugin; + + if (!String.IsNullOrEmpty(fault.TraceText)) + msg += "\r\nTrace log: " + fault.TraceText; + } + } + + return msg; + } + private string GetDisplayName(int count, EntityMetadata meta) { if (count == 1) @@ -676,6 +725,12 @@ private ExecutionPlanNode ConvertExecutionPlanNode(IExecutionPlanNode node, Time converted.Type = "languageConstructCatchAll"; else if (converted.Type == "xmlWriter") converted.Type = "udx"; + else if (converted.Type == "adaptiveIndexSpool") + converted.Type = "indexSpool"; + else if (converted.Type == "openJson") + converted.Type = "tableValuedFunction"; + else if (converted.Type == "systemFunction") + converted.Type = "tableValuedFunction"; // Get the filtered list of properties var typeDescriptor = new ExecutionPlanNodeTypeDescriptor(node, !executed, _ => null); diff --git a/MarkMpn.Sql4Cds.SSMS/Reflection/DisplaySQLResultsControlWrapper.cs b/MarkMpn.Sql4Cds.SSMS/Reflection/DisplaySQLResultsControlWrapper.cs index 2d2ba086..c3484ddb 100644 --- a/MarkMpn.Sql4Cds.SSMS/Reflection/DisplaySQLResultsControlWrapper.cs +++ b/MarkMpn.Sql4Cds.SSMS/Reflection/DisplaySQLResultsControlWrapper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; @@ -62,8 +63,9 @@ public void StartExecution() if (VersionChecker.Result.IsCompleted && !VersionChecker.Result.IsFaulted && VersionChecker.Result.Result > currentVersion) { + var ssmsVersion = Process.GetCurrentProcess().MainModule.FileVersionInfo.ProductMajorPart; AddStringToErrors(" An updated version of SQL 4 CDS is available", true); - AddStringToMessages($" Update to v{VersionChecker.Result.Result.ToString(3)} available from https://markcarrington.dev/sql-4-cds/"); + AddStringToMessages($" Update to v{VersionChecker.Result.Result.ToString(3)} available from https://github.com/MarkMpn/Sql4Cds/releases/download/v{VersionChecker.Result.Result.ToString(3)}/MarkMpn.Sql4Cds.SSMS.{ssmsVersion}.Setup.msi"); AddStringToMessages(""); } } diff --git a/MarkMpn.Sql4Cds.Tests/AutocompleteTests.cs b/MarkMpn.Sql4Cds.Tests/AutocompleteTests.cs index 08d78322..81fa4c11 100644 --- a/MarkMpn.Sql4Cds.Tests/AutocompleteTests.cs +++ b/MarkMpn.Sql4Cds.Tests/AutocompleteTests.cs @@ -390,5 +390,19 @@ DECLARE @x varchar CollectionAssert.IsSubsetOf(new[] { "@i", "@x", "@@ROWCOUNT", "@@IDENTITY", "@@SERVERNAME", "@@VERSION" }, suggestions); } + + [TestMethod] + public void SuggestVariablesWithoutFrom() + { + var sql = @" + DECLARE @i int + DECLARE @x varchar + + SELECT "; + + var suggestions = _autocomplete.GetSuggestions(sql, sql.Length - 1).Select(s => s.Text).ToList(); + + CollectionAssert.IsSubsetOf(new[] { "@i", "@x", "@@ROWCOUNT", "@@IDENTITY", "@@SERVERNAME", "@@VERSION" }, suggestions); + } } } diff --git a/MarkMpn.Sql4Cds.XTB/Autocomplete.cs b/MarkMpn.Sql4Cds.XTB/Autocomplete.cs index 492e40ff..1de56c50 100644 --- a/MarkMpn.Sql4Cds.XTB/Autocomplete.cs +++ b/MarkMpn.Sql4Cds.XTB/Autocomplete.cs @@ -568,13 +568,15 @@ public IEnumerable GetSuggestions(string text, int pos) { // Check if there are any applicable filter operator functions that match the type of the current attribute var identifiers = prevPrevWord.Split('.'); + var instance = default(AutocompleteDataSource); + var entity = default(EntityMetadata); var attribute = default(AttributeMetadata); if (identifiers.Length == 2) { if (tables.TryGetValue(identifiers[0], out var tableName)) { - if (TryParseTableName(tableName, out var instanceName, out _, out tableName) && _dataSources.TryGetValue(instanceName, out var instance) && instance.Metadata.TryGetMinimalData(tableName, out var entity)) + if (TryParseTableName(tableName, out var instanceName, out _, out tableName) && _dataSources.TryGetValue(instanceName, out instance) && instance.Metadata.TryGetMinimalData(tableName, out entity)) { attribute = entity.Attributes.SingleOrDefault(a => a.LogicalName.Equals(identifiers[1], StringComparison.OrdinalIgnoreCase)); } @@ -584,7 +586,7 @@ public IEnumerable GetSuggestions(string text, int pos) { foreach (var table in tables.Values) { - if (TryParseTableName(table, out var instanceName, out _, out var tableName) && _dataSources.TryGetValue(instanceName, out var instance) && instance.Metadata.TryGetMinimalData(tableName, out var entity)) + if (TryParseTableName(table, out var instanceName, out _, out var tableName) && _dataSources.TryGetValue(instanceName, out instance) && instance.Metadata.TryGetMinimalData(tableName, out entity)) { var tableAttribute = entity.Attributes.SingleOrDefault(a => a.LogicalName.Equals(identifiers[0], StringComparison.OrdinalIgnoreCase)); @@ -623,8 +625,25 @@ public IEnumerable GetSuggestions(string text, int pos) items.AddRange(typeof(FetchXmlConditionMethods).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.GetParameters()[0].ParameterType == expectedType).Select(m => new FunctionAutocompleteItem(m, currentLength))); } - if (attribute is EnumAttributeMetadata enumAttr) + if (attribute is EntityNameAttributeMetadata entityNameAttr) + { + var lookupAttr = entity.Attributes.SingleOrDefault(a => a.LogicalName == entityNameAttr.AttributeOf) as LookupAttributeMetadata; + + if (lookupAttr?.Targets == null || lookupAttr.Targets.Length == 0) + { + // Could be any entity name, show them all + items.AddRange(instance.Entities.Select(e => new EntityNameAutocompleteItem(e, currentLength))); + } + else + { + // Can only be one of the allowed entity types + items.AddRange(instance.Entities.Where(e => lookupAttr.Targets.Contains(e.LogicalName)).Select(e => new EntityNameAutocompleteItem(e, currentLength))); + } + } + else if (attribute is EnumAttributeMetadata enumAttr) + { items.AddRange(enumAttr.OptionSet.Options.Select(o => new OptionSetAutocompleteItem(o, currentLength))); + } } } @@ -1782,6 +1801,33 @@ public override string ToolTipText } } + class EntityNameAutocompleteItem : SqlAutocompleteItem + { + private readonly EntityMetadata _entity; + + public EntityNameAutocompleteItem(EntityMetadata entity, int replaceLength) : base(entity.LogicalName, replaceLength, 11) + { + _entity = entity; + } + + public override string ToolTipTitle + { + get => _entity.DisplayName?.UserLocalizedLabel?.Label ?? _entity.LogicalName; + set => base.ToolTipTitle = value; + } + + public override string ToolTipText + { + get => _entity.Description?.UserLocalizedLabel?.Label; + set => base.ToolTipText = value; + } + + public override string GetTextForReplace() + { + return "'" + _entity.LogicalName + "'"; + } + } + class CollationAutocompleteItem : SqlAutocompleteItem { private readonly Collation _collation; diff --git a/MarkMpn.Sql4Cds.XTB/FindReplace.Designer.cs b/MarkMpn.Sql4Cds.XTB/FindReplace.Designer.cs index 34c49d6d..9900f0d2 100644 --- a/MarkMpn.Sql4Cds.XTB/FindReplace.Designer.cs +++ b/MarkMpn.Sql4Cds.XTB/FindReplace.Designer.cs @@ -155,6 +155,7 @@ private void InitializeComponent() this.replaceToolStripButton.Name = "replaceToolStripButton"; this.replaceToolStripButton.Size = new System.Drawing.Size(23, 20); this.replaceToolStripButton.Text = "Replace Next"; + this.replaceToolStripButton.ToolTipText = "Replace Next (Alt+A)"; this.replaceToolStripButton.Click += new System.EventHandler(this.replaceToolStripButton_Click); // // replaceAllToolStripButton @@ -165,6 +166,7 @@ private void InitializeComponent() this.replaceAllToolStripButton.Name = "replaceAllToolStripButton"; this.replaceAllToolStripButton.Size = new System.Drawing.Size(23, 20); this.replaceAllToolStripButton.Text = "Replace All"; + this.replaceAllToolStripButton.ToolTipText = "Replace All (Alt+R)"; this.replaceAllToolStripButton.Click += new System.EventHandler(this.replaceAllToolStripButton_Click); // // optionsSpacerToolStripLabel diff --git a/MarkMpn.Sql4Cds.XTB/FindReplace.cs b/MarkMpn.Sql4Cds.XTB/FindReplace.cs index df007127..654a1f9e 100644 --- a/MarkMpn.Sql4Cds.XTB/FindReplace.cs +++ b/MarkMpn.Sql4Cds.XTB/FindReplace.cs @@ -132,6 +132,18 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) return true; } + if (keyData == (Keys.Alt | Keys.R) && ShowReplace) + { + Replace(false); + return true; + } + + if (keyData == (Keys.Alt | Keys.A) && ShowReplace) + { + Replace(true); + return true; + } + return base.ProcessCmdKey(ref msg, keyData); } @@ -176,6 +188,7 @@ public void FindNext() if (match != -1) { _editor.SetSelection(_editor.TargetStart, _editor.TargetEnd); + _editor.ScrollCaret(); break; } else if (_editor.TargetStart > 0) @@ -219,6 +232,7 @@ public void FindPrevious() if (match != -1) { _editor.SetSelection(_editor.TargetStart, _editor.TargetEnd); + _editor.ScrollCaret(); break; } else if (_editor.TargetStart < _editor.TextLength) @@ -252,7 +266,7 @@ private void replaceAllToolStripButton_Click(object sender, EventArgs e) Replace(true); } - private void Replace(bool all) + public void Replace(bool all) { AddHistory(findToolStripComboBox); AddHistory(replaceToolStripComboBox); @@ -273,20 +287,28 @@ private void Replace(bool all) _editor.TargetStart = all ? 0 : _editor.SelectionStart + 1; _editor.TargetEnd = _editor.TextLength; + var replacements = 0; + var lastMatch = -1; + var lastReplacementLength = 0; + while (true) { var match = _editor.SearchInTarget(findToolStripComboBox.Text); if (match != -1) { + lastMatch = match; + if (regexToolStripButton.Checked) - _editor.ReplaceTargetRe(replaceToolStripComboBox.Text); + lastReplacementLength = _editor.ReplaceTargetRe(replaceToolStripComboBox.Text); else - _editor.ReplaceTarget(replaceToolStripComboBox.Text); + lastReplacementLength = _editor.ReplaceTarget(replaceToolStripComboBox.Text); if (!all) break; + replacements++; + _editor.TargetStart = _editor.TargetEnd; _editor.TargetEnd = _editor.TextLength; } @@ -301,6 +323,15 @@ private void Replace(bool all) } _editor.EndUndoAction(); + + if (replacements > 0) + { + _editor.SetSelection(lastMatch, lastMatch + lastReplacementLength); + _editor.ScrollCaret(); + } + + if (all) + MessageBox.Show($"{replacements} occurrence(s) replaced.", "Replace All", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } diff --git a/MarkMpn.Sql4Cds.XTB/FindReplace.resx b/MarkMpn.Sql4Cds.XTB/FindReplace.resx index 4e24c47e..eaf5e9df 100644 --- a/MarkMpn.Sql4Cds.XTB/FindReplace.resx +++ b/MarkMpn.Sql4Cds.XTB/FindReplace.resx @@ -128,21 +128,12 @@ aC/86M4GG1mxO/tV6P5/X0LdECIa+LlhL/sRY3zmnD8ppZFPM7ghQ4dPLSxP1lry3lM9gjduyNDpjpTg FUIgrTUZY+YRkXFDhg66rC2U/z1K+e2ca0ZqGRk66LLW0hv5WxbWI4dkoR45LAsyckoWIJ6Wr4JSXwmW 2bf59kcYAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACZSURBVDhPYyAEvn//nvzp0ydRKJc08O3bt4rXr1//B9KX - STYEpPnu3bv/Q0ND/y9cuJA0Q/7//88B0rBq1ar/Tk5OYEyyISCFIA0gjbQ1BMgBCRDEOA0BScIkSMEw - Q6hjADF42rRpGJoJBiZRgYgLUKQZlpBWrFhBumYYACquuHbt2v+AgADSNcMAyJAXL16QpxkG8GdnBgYA - FtuEliCNINgAAAAASUVORK5CYII= iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - xAAADsQBlSsOGwAAAJpJREFUOE+1k7kNQyEQRAndwG+ICkiowE38SsjJEO1YIiNHIiddzyJvZP1jkT3S + wwAADsMBx2+oZAAAAJpJREFUOE+1k7kNQyEQRAndwG+ICkiowE38SsjJEO1YIiNHIiddzyJvZP1jkT3S iGvfSFzmSmOMJ7x9hjoB3HvvhPalDmG41kree4ox6kJQ+GAg50zW2umVkI0BBv8bgg5PXPowhBdlQWMJ +U3AHYcQvmB4buHMtw7xyOvXiIL5kFJKeliEwr2UQs45PSzikNbaGiwCePKdjXkDE3GqrEJQ/eEAAAAA SUVORK5CYII= @@ -151,10 +142,19 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - xAAADsQBlSsOGwAAAJdJREFUOE9jwAW+ffsmCsTJUC5pAKr58uvXr/8D6QqoMHEApnnhwoX/Q0ND/9+9 + wwAADsMBx2+oZAAAAJdJREFUOE9jwAW+ffsmCsTJUC5pAKr58uvXr/8D6QqoMHEApnnhwoX/Q0ND/9+9 e5d4Q5A1Ozk5gfGqVatABlwGYg6oMuwAm2YQG6pZFKoMO6CVZqIwyAAUzaRgqhmA4YVp06ahOBMfJhQO 4EAEYpAarBgOgByyDEEBQAEMQ4hOSDCAbAjJSRkGYIaQlZlgAGoIgezMwAAAzlaq30/lAWMAAAAASUVO RK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACZSURBVDhPYyAEvn//nvzp0ydRKJc08O3bt4rXr1//B9KX + STYEpPnu3bv/Q0ND/y9cuJA0Q/7//88B0rBq1ar/Tk5OYEyyISCFIA0gjbQ1BMgBCRDEOA0BScIkSMEw + Q6hjADF42rRpGJoJBiZRgYgLUKQZlpBWrFhBumYYACquuHbt2v+AgADSNcMAyJAXL16QpxkG8GdnBgYA + FtuEliCNINgAAAAASUVORK5CYII= @@ -208,13 +208,13 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFOSURBVDhPzVK/S8NAFI6Lg6M4iKv/hGuCg2R1LATBxQ5C - QyFLoFMHs+WP6OQgDckYFff+AWKJcaqBZEjzE4r1+d1xCjWHOPaDB+/ufd93996dsp0got22bS/KsqQ0 - TSnLMloulx/Y3xOUv1HX9UPTNHdRFJGmadTv9wnr96qqnlC7EjQ5QDhaLBafnucRcm7gui4lSUK+77O9 - e0GVA4TrIAhIVVUu7vV6ZFkWz1nAaJ3n+b6gdwGDR2YwGo341ZlI13UaDoc0Ho9pPp8T5nMp6JvAkHbQ - qwWTZzY80zTJMAxuMplM2BxY3GIWupB0AfE5Iw4GAy4Mw5Bs2+b5dDqloijepK8h3H8ijmPeO/pdz2Yz - chyHcHKKA06EZBNMxAb3HWyNt19BcIP/8ArxC3o/FvQuZAYQnEJ4iDjD1Q8EVQ6ZgSj9D0zwO0Rpq6Eo - X0BoPgmkWlyhAAAAAElFTkSuQmCC + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFPSURBVDhPzVIxS8NAGI2Lg6M4iKt/wrXBQbI6BoLgYgYh + IZAlkKmD2fIjMjlISjtGxb0/QAwxLiGFBBLSNAWxfr47TqE2iGMffHB333vv7nuJtJ0got3lcnkxn8+p + KAoqy5Lquv7A+Z6g/I3FYvHQdd1dkiQkyzLpuk7Y523bPqF3JWj9AOEoy7LP0WhEWHMD3/dpNpvReDxm + Z/eC2g8QrieTCQ0GAy5WVZVs2+ZrVnmerzDOvqBvAgaPzMB1Xf50JlIUhSzLouFwSHEcE/K5FPR1IKQd + zGrD5JmFZ5omaZrGTYIgYDmwukUWipBsAuJzRjQMgwujKCLHcfg6DENqmuat92sI959K05TPXlXVajqd + kud5hJsLXHAiJOtgIhbcd7E9wnqH4Ab/wyvEL5j9WNA30WcAwSmEh6gzPP1AUPvRZyBa/wMT/C7R2mpI + 0hccaD36l+69nwAAAABJRU5ErkJggg== \ No newline at end of file diff --git a/MarkMpn.Sql4Cds.XTB/FunctionMetadata.cs b/MarkMpn.Sql4Cds.XTB/FunctionMetadata.cs index da81ce41..f9dcbe3e 100644 --- a/MarkMpn.Sql4Cds.XTB/FunctionMetadata.cs +++ b/MarkMpn.Sql4Cds.XTB/FunctionMetadata.cs @@ -58,6 +58,12 @@ public abstract class SqlFunctions [Description("Extracts a scalar value from a JSON string")] public abstract string json_value(string json, string path); + [Description("Extracts an object or an array from a JSON string")] + public abstract string json_query(string json, string path); + + [Description("Tests whether a string contains valid JSON")] + public abstract string isjson(string json, string type); + [Description("Tests whether a specified SQL/JSON path exists in the input JSON string")] public abstract bool json_path_exists(string json, string path); diff --git a/MarkMpn.Sql4Cds.XTB/MarkMpn.Sql4Cds.XTB.csproj b/MarkMpn.Sql4Cds.XTB/MarkMpn.Sql4Cds.XTB.csproj index 90d3bd8f..4bb95bff 100644 --- a/MarkMpn.Sql4Cds.XTB/MarkMpn.Sql4Cds.XTB.csproj +++ b/MarkMpn.Sql4Cds.XTB/MarkMpn.Sql4Cds.XTB.csproj @@ -66,6 +66,7 @@ + True True @@ -281,7 +282,7 @@ - 1.2023.7.65 + 1.2023.10.67 diff --git a/MarkMpn.Sql4Cds.XTB/MessageBoxExt.cs b/MarkMpn.Sql4Cds.XTB/MessageBoxExt.cs new file mode 100644 index 00000000..bdb87f9a --- /dev/null +++ b/MarkMpn.Sql4Cds.XTB/MessageBoxExt.cs @@ -0,0 +1,431 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.Activities; + +// https://learn.microsoft.com/en-us/archive/msdn-magazine/2002/november/cutting-edge-using-windows-hooks-to-enhance-messagebox-in-net + +namespace MarkMpn.Sql4Cds.XTB +{ + static class YesYesToAllNoMessageBox + { + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern bool SetWindowText(IntPtr hwnd, String lpString); + + [DllImport("user32.dll")] + static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem); + + public static DialogResult Show(IWin32Window owner, string text, string title, MessageBoxIcon icon, out bool all) + { + var cbt = new LocalCbtHook(); + var handle = IntPtr.Zero; + var alreadySetup = false; + + cbt.WindowCreated += (sender, e) => + { + if (e.IsDialogWindow) + { + alreadySetup = false; + handle = e.Handle; + } + }; + + cbt.WindowActivated += (sender, e) => + { + if (e.Handle == handle && !alreadySetup) + { + alreadySetup = true; + + // Map button text + SetWindowText(GetDlgItem(handle, (int)DialogResult.No), "Yes to &All"); + SetWindowText(GetDlgItem(handle, (int)DialogResult.Cancel), DialogResult.No.ToString()); + } + }; + + cbt.WindowDestroyed += (sender, e) => + { + if (e.Handle == handle) + { + alreadySetup = false; + handle = IntPtr.Zero; + } + }; + + cbt.Install(); + + try + { + var result = MessageBox.Show(owner, text, title, MessageBoxButtons.YesNoCancel, icon, MessageBoxDefaultButton.Button3); + + switch (result) + { + case DialogResult.Yes: + all = false; + return DialogResult.Yes; + + case DialogResult.No: + all = true; + return DialogResult.Yes; + + case DialogResult.Cancel: + all = false; + return DialogResult.No; + + default: + all = false; + return result; + } + } + finally + { + cbt.Uninstall(); + } + } + } + + // CBT hook actions + enum CbtHookAction + { + HCBT_MOVESIZE = 0, + HCBT_MINMAX = 1, + HCBT_QS = 2, + HCBT_CREATEWND = 3, + HCBT_DESTROYWND = 4, + HCBT_ACTIVATE = 5, + HCBT_CLICKSKIPPED = 6, + HCBT_KEYSKIPPED = 7, + HCBT_SYSCOMMAND = 8, + HCBT_SETFOCUS = 9 + } + + class CbtEventArgs : EventArgs + { + /// + /// Win32 handle of the window + /// + public IntPtr Handle { get; set; } + + /// + /// caption of the window + /// + public string Title { get; set; } + + /// + /// class of the window + /// + public string ClassName { get; set; } + + /// + /// whether it's a popup dialog + /// + public bool IsDialogWindow { get; set; } + } + + /// + /// Event delegate + /// + /// + /// + delegate void CbtEventHandler(object sender, CbtEventArgs e); + + class LocalCbtHook : LocalWindowsHook + { + public event CbtEventHandler WindowCreated; + public event CbtEventHandler WindowDestroyed; + public event CbtEventHandler WindowActivated; + + private IntPtr _hwnd; + private string _title; + private string _class; + private bool _isDialog; + + public LocalCbtHook() : base(HookType.WH_CBT) + { + HookInvoked += new HookEventHandler(CbtHookInvoked); + } + + public LocalCbtHook(HookProc func) : base(HookType.WH_CBT, func) + { + HookInvoked += new HookEventHandler(CbtHookInvoked); + } + + /// + /// Handles the hook event + /// + /// + /// + private void CbtHookInvoked(object sender, HookEventArgs e) + { + var code = (CbtHookAction)e.HookCode; + var wParam = e.wParam; + var lParam = e.lParam; + + // Handle hook events (only a few of available actions) + switch (code) + { + case CbtHookAction.HCBT_CREATEWND: + HandleCreateWndEvent(wParam, lParam); + break; + + case CbtHookAction.HCBT_DESTROYWND: + HandleDestroyWndEvent(wParam, lParam); + break; + + case CbtHookAction.HCBT_ACTIVATE: + HandleActivateEvent(wParam, lParam); + break; + } + + return; + } + + /// + /// Handle the CREATEWND hook event + /// + /// + /// + private void HandleCreateWndEvent(IntPtr wParam, IntPtr lParam) + { + // Cache some information + UpdateWindowData(wParam); + + // raise event + OnWindowCreated(); + } + + /// + /// Handle the DESTROYWND hook event + /// + /// + /// + private void HandleDestroyWndEvent(IntPtr wParam, IntPtr lParam) + { + // Cache some information + UpdateWindowData(wParam); + + // raise event + OnWindowDestroyed(); + } + + /// + /// Handle the ACTIVATE hook event + /// + /// + /// + private void HandleActivateEvent(IntPtr wParam, IntPtr lParam) + { + // Cache some information + UpdateWindowData(wParam); + + // raise event + OnWindowActivated(); + } + + /// + /// Read and store some information about the window + /// + /// + private void UpdateWindowData(IntPtr wParam) + { + // Cache the window handle + _hwnd = wParam; + + // Cache the window's class name + var className = new StringBuilder(40); + GetClassName(_hwnd, className, 40); + _class = className.ToString(); + + // Cache the window's title bar + var text = new StringBuilder(256); + GetWindowText(_hwnd, text, 256); + _title = text.ToString(); + + // Cache the dialog flag + _isDialog = _class == "#32770"; + } + + /// + /// Helper functions that fire events by executing user code + /// + protected virtual void OnWindowCreated() + { + if (WindowCreated != null) + { + var e = new CbtEventArgs(); + PrepareEventData(e); + WindowCreated(this, e); + } + } + + protected virtual void OnWindowDestroyed() + { + if (WindowDestroyed != null) + { + CbtEventArgs e = new CbtEventArgs(); + PrepareEventData(e); + WindowDestroyed(this, e); + } + } + + protected virtual void OnWindowActivated() + { + if (WindowActivated != null) + { + CbtEventArgs e = new CbtEventArgs(); + PrepareEventData(e); + WindowActivated(this, e); + } + } + + /// + /// Prepare the event data structure + /// + /// + private void PrepareEventData(CbtEventArgs e) + { + e.Handle = _hwnd; + e.Title = _title; + e.ClassName = _class; + e.IsDialogWindow = _isDialog; + } + + [DllImport("user32.dll")] + private static extern int GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("user32.dll")] + private static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount); + } + + class HookEventArgs : EventArgs + { + /// + /// Hook code + /// + public int HookCode { get; set; } + + /// + /// WPARAM argument + /// + public IntPtr wParam { get; set; } + + /// + /// LPARAM argument + /// + public IntPtr lParam { get; set; } + } + + // Hook Types + enum HookType + { + WH_JOURNALRECORD = 0, + WH_JOURNALPLAYBACK = 1, + WH_KEYBOARD = 2, + WH_GETMESSAGE = 3, + WH_CALLWNDPROC = 4, + WH_CBT = 5, + WH_SYSMSGFILTER = 6, + WH_MOUSE = 7, + WH_HARDWARE = 8, + WH_DEBUG = 9, + WH_SHELL = 10, + WH_FOREGROUNDIDLE = 11, + WH_CALLWNDPROCRET = 12, + WH_KEYBOARD_LL = 13, + WH_MOUSE_LL = 14 + } + + class LocalWindowsHook + { + private IntPtr _hhook; + private HookProc _filterFunc; + private HookType _hookType; + + public event HookEventHandler HookInvoked; + + protected void OnHookInvoked(HookEventArgs e) + { + if (HookInvoked != null) + HookInvoked(this, e); + } + + public LocalWindowsHook(HookType hook) + { + _hookType = hook; + _filterFunc = new HookProc(this.CoreHookProc); + } + + public LocalWindowsHook(HookType hook, HookProc func) + { + _hookType = hook; + _filterFunc = func; + } + + /// + /// Default filter function + /// + /// + /// + /// + /// + public int CoreHookProc(int code, IntPtr wParam, IntPtr lParam) + { + if (code < 0) + return CallNextHookEx(_hhook, code, wParam, lParam); + + // Let clients determine what to do + var e = new HookEventArgs + { + HookCode = code, + wParam = wParam, + lParam = lParam + }; + + OnHookInvoked(e); + + // Yield to the next hook in the chain + return CallNextHookEx(_hhook, code, wParam, lParam); + } + + /// + /// Install the hook + /// + public void Install() + { + _hhook = SetWindowsHookEx(_hookType, _filterFunc, IntPtr.Zero, AppDomain.GetCurrentThreadId()); + } + + /// + /// Uninstall the hook + /// + public void Uninstall() + { + UnhookWindowsHookEx(_hhook); + } + + [DllImport("user32.dll")] + private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID); + + [DllImport("user32.dll")] + private static extern int UnhookWindowsHookEx(IntPtr hhook); + + [DllImport("user32.dll")] + private static extern int CallNextHookEx(IntPtr hhook, int code, IntPtr wParam, IntPtr lParam); + } + + /// + /// Filter function delegate + /// + /// + /// + /// + /// + delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); + + /// + /// Event delegate + /// + /// + /// + delegate void HookEventHandler(object sender, HookEventArgs e); +} diff --git a/MarkMpn.Sql4Cds.XTB/QueryExecutionOptions.cs b/MarkMpn.Sql4Cds.XTB/QueryExecutionOptions.cs index b34fd529..4fe682c5 100644 --- a/MarkMpn.Sql4Cds.XTB/QueryExecutionOptions.cs +++ b/MarkMpn.Sql4Cds.XTB/QueryExecutionOptions.cs @@ -22,6 +22,7 @@ class QueryExecutionOptions : IDisposable private readonly Sql4CdsConnection _con; private readonly Sql4CdsCommand _cmd; private int _retrievedPages; + private bool _suppressWarnings; public QueryExecutionOptions(Control host, BackgroundWorker worker, Sql4CdsConnection con, Sql4CdsCommand cmd) { @@ -60,7 +61,7 @@ private void ConfirmInsert(object sender, ConfirmDmlStatementEventArgs e) private bool ConfirmInsert(Sql4CdsConnection con, ConfirmDmlStatementEventArgs e) { - if (e.Count > Settings.Instance.InsertWarnThreshold || e.BypassCustomPluginExecution) + if ((e.Count > Settings.Instance.InsertWarnThreshold || e.BypassCustomPluginExecution) && !_suppressWarnings) { var msg = $"Insert will affect {e.Count:N0} {GetDisplayName(e.Count, e.Metadata)}."; if (e.BypassCustomPluginExecution) @@ -82,7 +83,7 @@ private void ConfirmUpdate(object sender, ConfirmDmlStatementEventArgs e) private bool ConfirmUpdate(Sql4CdsConnection con, ConfirmDmlStatementEventArgs e) { - if (e.Count > Settings.Instance.UpdateWarnThreshold || e.BypassCustomPluginExecution) + if ((e.Count > Settings.Instance.UpdateWarnThreshold || e.BypassCustomPluginExecution) && !_suppressWarnings) { var msg = $"Update will affect {e.Count:N0} {GetDisplayName(e.Count, e.Metadata)}."; if (e.BypassCustomPluginExecution) @@ -104,7 +105,7 @@ private void ConfirmDelete(object sender, ConfirmDmlStatementEventArgs e) private bool ConfirmDelete(Sql4CdsConnection con, ConfirmDmlStatementEventArgs e) { - if (e.Count > Settings.Instance.DeleteWarnThreshold || e.BypassCustomPluginExecution) + if ((e.Count > Settings.Instance.DeleteWarnThreshold || e.BypassCustomPluginExecution) && !_suppressWarnings) { var msg = $"Delete will affect {e.Count:N0} {GetDisplayName(e.Count, e.Metadata)}."; if (e.BypassCustomPluginExecution) @@ -170,7 +171,7 @@ private DialogResult ShowMessageBox(string msg) if (_host.InvokeRequired) return (DialogResult)_host.Invoke(new Func(ShowMessageBox), msg); - return MessageBox.Show(_host, msg + "\r\n\r\nDo you want to proceed?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2); + return YesYesToAllNoMessageBox.Show(_host, msg + "\r\n\r\nDo you want to proceed?", "Confirm", MessageBoxIcon.Warning, out _suppressWarnings); } public void Dispose() diff --git a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.Designer.cs b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.Designer.cs index be408829..8fb4f589 100644 --- a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.Designer.cs +++ b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.Designer.cs @@ -43,6 +43,7 @@ private void InitializeComponent() this.copyWithHeadersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.openRecordToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyRecordUrlToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.createSELECTStatementToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip = new System.Windows.Forms.StatusStrip(); this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); @@ -176,9 +177,10 @@ private void InitializeComponent() this.copyWithHeadersToolStripMenuItem, this.toolStripMenuItem1, this.openRecordToolStripMenuItem, + this.copyRecordUrlToolStripMenuItem, this.createSELECTStatementToolStripMenuItem}); this.gridContextMenuStrip.Name = "gridContextMenuStrip"; - this.gridContextMenuStrip.Size = new System.Drawing.Size(207, 98); + this.gridContextMenuStrip.Size = new System.Drawing.Size(207, 142); this.gridContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.gridContextMenuStrip_Opening); // // copyToolStripMenuItem @@ -208,6 +210,14 @@ private void InitializeComponent() this.openRecordToolStripMenuItem.Text = "Open Record"; this.openRecordToolStripMenuItem.Click += new System.EventHandler(this.openRecordToolStripMenuItem_Click); // + // copyRecordUrlToolStripMenuItem + // + this.copyRecordUrlToolStripMenuItem.Enabled = false; + this.copyRecordUrlToolStripMenuItem.Name = "copyRecordUrlToolStripMenuItem"; + this.copyRecordUrlToolStripMenuItem.Size = new System.Drawing.Size(206, 22); + this.copyRecordUrlToolStripMenuItem.Text = "Copy Record Url"; + this.copyRecordUrlToolStripMenuItem.Click += new System.EventHandler(this.copyRecordUrlToolStripMenuItem_Click); + // // createSELECTStatementToolStripMenuItem // this.createSELECTStatementToolStripMenuItem.Enabled = false; @@ -378,5 +388,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem openRecordToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem createSELECTStatementToolStripMenuItem; private System.Windows.Forms.Label environmentHighlightLabel; + private System.Windows.Forms.ToolStripMenuItem copyRecordUrlToolStripMenuItem; } } diff --git a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.cs b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.cs index 5daf414a..c7d7a3c6 100644 --- a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.cs +++ b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.cs @@ -235,8 +235,127 @@ public void Format() if (errors.Count != 0) return; - new Sql160ScriptGenerator().GenerateScript(fragment, out var sql); - _editor.Text = sql; + var tokens = new Sql160ScriptGenerator().GenerateTokens(fragment); + + // Insert any comments from the original tokens. Ignore whitespace tokens. + for (int srcIndex = 0, dstIndex = -1; srcIndex < fragment.ScriptTokenStream.Count; srcIndex++) + { + var token = fragment.ScriptTokenStream[srcIndex]; + + if (token.TokenType == TSqlTokenType.WhiteSpace) + continue; + + if (token.TokenType == TSqlTokenType.MultilineComment || token.TokenType == TSqlTokenType.SingleLineComment) + { + // dstIndex currently points to the previously matched token. Move forward one so we insert the comment after that token + dstIndex++; + + // We may well have added a semicolon at the end of the statement - move after that too + if ((srcIndex == fragment.ScriptTokenStream.Count - 1 || fragment.ScriptTokenStream[srcIndex + 1].TokenType != TSqlTokenType.Semicolon) && + dstIndex <= tokens.Count - 1 && + tokens[dstIndex].TokenType == TSqlTokenType.Semicolon) + dstIndex++; + + // Also skip over any matching whitespace + var whitespaceCount = 0; + + while (dstIndex + whitespaceCount < tokens.Count && + srcIndex - whitespaceCount - 1 >= 0 && + IsMatchingWhitespace(tokens[dstIndex + whitespaceCount], fragment.ScriptTokenStream[srcIndex - whitespaceCount - 1])) + whitespaceCount++; + + CopyComment(fragment.ScriptTokenStream, srcIndex, tokens, dstIndex + whitespaceCount); + } + else + { + dstIndex++; + + while (dstIndex < tokens.Count && !IsSameType(token, tokens[dstIndex])) + dstIndex++; + } + } + + using (var writer = new StringWriter()) + { + foreach (var token in tokens) + writer.Write(token.Text); + + writer.Flush(); + + _editor.Text = writer.ToString(); + } + } + + private bool IsSameType(TSqlParserToken srcToken, TSqlParserToken dstToken) + { + if (srcToken.TokenType == dstToken.TokenType) + return true; + + if (srcToken.TokenType == TSqlTokenType.Variable && dstToken.TokenType == TSqlTokenType.Identifier && dstToken.Text.StartsWith("@")) + return true; + + return false; + } + + private void CopyComment(IList src, int srcIndex, IList dst, int dstIndex) + { + if (dstIndex >= dst.Count) + dst.Add(src[srcIndex]); + else + dst.Insert(dstIndex, src[srcIndex]); + + // Also add any leading or trailing whitespace + var leadingSrcIndex = srcIndex - 1; + var leadingDstIndex = dstIndex - 1; + var insertPoint = dstIndex; + + while (leadingSrcIndex >= 0 && src[leadingSrcIndex].TokenType == TSqlTokenType.WhiteSpace) + { + if (IsMatchingWhitespace(dst[leadingDstIndex], src[leadingSrcIndex])) + break; + + dst.Insert(insertPoint, src[leadingSrcIndex]); + leadingSrcIndex--; + leadingDstIndex--; + dstIndex++; + } + + var trailingSrcIndex = srcIndex + 1; + var trailingDstIndex = dstIndex + 1; + + while (trailingSrcIndex < src.Count && src[trailingSrcIndex].TokenType == TSqlTokenType.WhiteSpace) + { + if (trailingDstIndex < dst.Count && IsMatchingWhitespace(dst[trailingDstIndex], src[trailingSrcIndex])) + break; + + if (trailingDstIndex >= dst.Count) + dst.Add(src[trailingSrcIndex]); + else + dst.Insert(trailingDstIndex, src[trailingSrcIndex]); + + trailingSrcIndex++; + trailingDstIndex++; + } + } + + private bool IsMatchingWhitespace(TSqlParserToken x, TSqlParserToken y) + { + if (x.TokenType != TSqlTokenType.WhiteSpace) + return false; + + if (y.TokenType != TSqlTokenType.WhiteSpace) + return false; + + if (x.Text == y.Text) + return true; + + if (x.Text == "\n" && y.Text == "\r\n") + return true; + + if (x.Text == "\r\n" && y.Text == "\n") + return true; + + return false; } private Scintilla CreateEditor() @@ -829,19 +948,25 @@ private string GetErrorMessage(Exception error) if (fault.Message != error.Message) msg += "\r\n" + fault.Message; + if (fault.ErrorDetails.TryGetValue("Plugin.ExceptionFromPluginExecute", out var plugin)) + msg += "\r\nError from plugin: " + plugin; + + if (!String.IsNullOrEmpty(fault.TraceText)) + msg += "\r\nTrace log: " + fault.TraceText; + while (fault.InnerFault != null) { if (fault.InnerFault.Message != fault.Message) msg += "\r\n" + fault.InnerFault.Message; fault = fault.InnerFault; - } - if (fault.ErrorDetails.TryGetValue("Plugin.ExceptionFromPluginExecute", out var plugin)) - msg += "\r\nError from plugin: " + plugin; + if (fault.ErrorDetails.TryGetValue("Plugin.ExceptionFromPluginExecute", out plugin)) + msg += "\r\nError from plugin: " + plugin; - if (!String.IsNullOrEmpty(fault.TraceText)) - msg += "\r\nTrace log: " + fault.TraceText; + if (!String.IsNullOrEmpty(fault.TraceText)) + msg += "\r\nTrace log: " + fault.TraceText; + } } return msg; @@ -1206,7 +1331,7 @@ private void ShowResult(IRootExecutionPlanNode query, ExecuteParams args, DataTa } else if (msg != null) { - AddMessage(query.Index, query.Length, msg, false); + AddMessage(query?.Index ?? -1, query?.Length ?? 0, msg, false); } else if (args.IncludeFetchXml) { @@ -1253,13 +1378,25 @@ private int BorderThickness(DataGridViewAdvancedCellBorderStyle style) } } + private string GetRecordUrl(SqlEntityReference entityReference, out XtbDataSource dataSource) + { + dataSource = null; + + if (!DataSources.TryGetValue(entityReference.DataSource, out var ds)) + return null; + + dataSource = (XtbDataSource)ds; + return dataSource.ConnectionDetail.GetEntityReferenceUrl(entityReference); + } + private void OpenRecord(SqlEntityReference entityReference) { - if (!DataSources.TryGetValue(entityReference.DataSource, out var dataSource)) + var url = GetRecordUrl(entityReference, out var dataSource); + + if (url == null) return; - var url = ((XtbDataSource) dataSource).ConnectionDetail.GetEntityReferenceUrl(entityReference); - ((XtbDataSource)dataSource).ConnectionDetail.OpenUrlWithBrowserProfile(new Uri(url)); + dataSource.ConnectionDetail.OpenUrlWithBrowserProfile(new Uri(url)); } private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) @@ -1389,11 +1526,13 @@ private void gridContextMenuStrip_Opening(object sender, CancelEventArgs e) var grid = (DataGridView)gridContextMenuStrip.SourceControl; openRecordToolStripMenuItem.Enabled = false; + copyRecordUrlToolStripMenuItem.Enabled = false; createSELECTStatementToolStripMenuItem.Enabled = false; if (grid.CurrentCell?.Value is SqlEntityReference er && !er.IsNull) { openRecordToolStripMenuItem.Enabled = true; + copyRecordUrlToolStripMenuItem.Enabled = true; createSELECTStatementToolStripMenuItem.Enabled = true; } @@ -1408,6 +1547,19 @@ private void openRecordToolStripMenuItem_Click(object sender, EventArgs e) OpenRecord(er); } + private void copyRecordUrlToolStripMenuItem_Click(object sender, EventArgs e) + { + var grid = (DataGridView)gridContextMenuStrip.SourceControl; + + if (grid.CurrentCell?.Value is SqlEntityReference er && !er.IsNull) + { + var url = GetRecordUrl(er, out _); + + if (url != null) + Clipboard.SetText(url); + } + } + private void createSELECTStatementToolStripMenuItem_Click(object sender, EventArgs e) { var grid = (DataGridView)gridContextMenuStrip.SourceControl; diff --git a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.resx b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.resx index a1f0afae..4b4bd978 100644 --- a/MarkMpn.Sql4Cds.XTB/SqlQueryControl.resx +++ b/MarkMpn.Sql4Cds.XTB/SqlQueryControl.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACM - CQAAAk1TRnQBSQFMAgEBAwEAAXABAAFwAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CQAAAk1TRnQBSQFMAgEBAwEAAYABAAGAAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/MarkMpn.Sql4Cds/MarkMpn.SQL4CDS.nuspec b/MarkMpn.Sql4Cds/MarkMpn.SQL4CDS.nuspec index b1eccd9c..23f58502 100644 --- a/MarkMpn.Sql4Cds/MarkMpn.SQL4CDS.nuspec +++ b/MarkMpn.Sql4Cds/MarkMpn.SQL4CDS.nuspec @@ -20,21 +20,43 @@ Supports Where possible the queries are converted to FetchXML, allowing you to generate FetchXML queries for plugins or integrations by writing familiar SQL and converting it. -Using the preview TDS Endpoint, SELECT queries can also be run that aren't convertible to FetchXML. +Queries can also run using the preview TDS Endpoint. A wide range of SQL functionality is also built +in to allow running queries that aren't directly supported by either FetchXML or the TDS Endpoint. Convert SQL queries to FetchXML and execute them against Dataverse / D365 - Fixed use of IN subqueries when data source cannot be converted to FetchXML -Fixed use of LIKE filters with data containing embedded returns -Fixed incorrect row count estimates with joins of huge tables -Fixed left outer join in nested loop when the first record has no matching records from the right source -Fixed use of partitioned aggregates within a loop -Avoid errors when using DEBUG_BYPASS_OPTIMIZATION hint -Avoid using custom paging for IN and EXISTS filters, and where a single child record is guaranteed by the filters + Added Common Table Expression support: +- Non-recursive CTEs are expanded to subqueries for compatibility with TDS Endpoint +- Recurve CTEs are converted to hierarchical FetchXML filters where possible + +Extended JSON support: +- OPENJSON table-valued function +- JSON_QUERY function +- ISJSON function + +Query optimizer improvements: +- Prefer hash joins over merge joins if sorts cannot be folded +- Switch FetchXML sorts to custom sorting after adding joins that require custom paging +- Avoid folding filters to tables in subqueries if the same alias exists in the outer query +- Do not use a left outer join to implement `NOT IN` queries where the subquery uses an inner join + +Added IGNORE_DUP_KEY query hint to ignore duplicate key errors on insert +Added check for multi-currency issues when aggregating non-base currency fields +Clearer progress messages for multi-threaded DML operations +Added autocomplete literal value suggestions for entityname attributes + +Fixed inconsistent display of plugin log messages in error message output +Fixed use of `UNION` with wildcard columns +Fixed error in nested loop joins with no records from inner source +Fixed use of columns from outer queries in join criteria in subqueries +Fixed time zone mismatch when starting bulk delete jobs +Fixed setting polymorphic lookup fields using TDS Endpoint +Fixed aggregates with very dense data distribution +Preserve comments when formatting query Copyright © 2019 Mark Carrington en-GB XrmToolBox SQL CDS - + diff --git a/MarkMpn.Sql4Cds/MarkMpn.Sql4Cds.csproj b/MarkMpn.Sql4Cds/MarkMpn.Sql4Cds.csproj index edc405c7..14525b16 100644 --- a/MarkMpn.Sql4Cds/MarkMpn.Sql4Cds.csproj +++ b/MarkMpn.Sql4Cds/MarkMpn.Sql4Cds.csproj @@ -96,7 +96,7 @@ 4.3.1 - 1.2023.6.65 + 1.2023.10.67 diff --git a/build.yml b/build.yml index ab3db880..6c0c1124 100644 --- a/build.yml +++ b/build.yml @@ -41,7 +41,7 @@ steps: - task: NodeTool@0 displayName: Install Node.js inputs: - versionSpec: '18.x' + versionSpec: '20.x' - task: DotNetCoreCLI@2 displayName: dotnet restore @@ -128,6 +128,8 @@ steps: - script: | call npm --no-git-tag-version version $(GitVersion.SemVer) call npm i -g vsce + call git config --global url."https://github".insteadOf ssh://git@github + call git config --global url."https://github.com/".insteadOf git@github.com: call yarn install call gulp build call gulp package:offline diff --git a/pr-build.yml b/pr-build.yml index c96958c7..bad453b6 100644 --- a/pr-build.yml +++ b/pr-build.yml @@ -57,11 +57,13 @@ steps: - task: NodeTool@0 displayName: Install Node.js inputs: - versionSpec: '18.x' + versionSpec: '20.x' - script: | call npm --no-git-tag-version version $(GitVersion.SemVer) call npm i -g vsce + call git config --global url."https://github".insteadOf ssh://git@github + call git config --global url."https://github.com/".insteadOf git@github.com: call yarn install call gulp build displayName: Build ADS extension