From 50317999bdb428b906c3a39418c45d6503de6f57 Mon Sep 17 00:00:00 2001 From: parallels999 <109294935+parallels999@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:04:33 -0500 Subject: [PATCH 01/12] Fix npm publish --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4053f5e..7f8d339 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,10 @@ "type": "git", "url": "https://github.com/goto100/xpath.git" }, - "main": "./xpath.js", + "main": "xpath.js", + "files": [ + "xpath.d.ts" + ], "keywords": [ "xpath", "xml" From 50357f146c018e11072dd66688357a4b9b03abc3 Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Tue, 25 Jul 2023 20:06:36 -0400 Subject: [PATCH 02/12] (fix): isArrayOfNodes input type not assignable to guarded type --- xpath.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xpath.d.ts b/xpath.d.ts index 9d1a734..3f59c6b 100644 --- a/xpath.d.ts +++ b/xpath.d.ts @@ -39,7 +39,7 @@ export function useNamespaces(namespaceMap: Record): XPathSelect // Type guards to narrow down the type of the selected type of a returned Node object export function isNodeLike(value: SelectedValue): value is Node; -export function isArrayOfNodes(value: SelectedValue): value is Node[]; +export function isArrayOfNodes(value: SelectReturnType): value is Node[]; export function isElement(value: SelectedValue): value is Element; export function isAttribute(value: SelectedValue): value is Attr; export function isTextNode(value: SelectedValue): value is Text; From a9e4e49a098e6311f2c352f0a8daef779d883326 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 17:38:26 +0900 Subject: [PATCH 03/12] [83] Address issues with sorting namespace nodes --- test.js | 23 ++++++++++++ xpath.js | 111 +++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 99 insertions(+), 35 deletions(-) diff --git a/test.js b/test.js index 962586d..18ba6b8 100644 --- a/test.js +++ b/test.js @@ -380,6 +380,29 @@ describe('xpath', () => { assert.strictEqual(1, lastChapter.length); assert.strictEqual("The burrow", lastChapter[0].textContent); }); + + it('should select and sort namespace nodes properly', () => { + const doc = parseXml(''); + + const namespaces = xpath.parse('/*/namespace::*').select({ node: doc }); + + assert.strictEqual(5, namespaces.length); + + assert.equal('http://www.w3.org/XML/1998/namespace', namespaces[0].nodeValue); + assert.equal('xml', namespaces[0].localName); + + assert.equal('http://book.com', namespaces[1].nodeValue); + assert.equal('b', namespaces[1].localName); + + assert.equal('default-book', namespaces[2].nodeValue); + assert.equal('', namespaces[2].localName); + + assert.equal('http://author.com', namespaces[3].nodeValue); + assert.equal('a', namespaces[3].localName); + + assert.equal('http://publisher', namespaces[4].nodeValue); + assert.equal('p', namespaces[4].localName); + }); }); describe('string()', () => { diff --git a/xpath.js b/xpath.js index 1189c1a..180a629 100644 --- a/xpath.js +++ b/xpath.js @@ -175,10 +175,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; for (var start = 0; start < arr.length; start += MAX_ARGUMENT_LENGTH) { var chunk = arr.slice(start, start + MAX_ARGUMENT_LENGTH); - + result = prototypeConcat.apply(result, chunk); } - + return result; } @@ -211,6 +211,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, + NAMESPACE_NODE: '__namespace', // not part of DOM model }; // XPathParser /////////////////////////////////////////////////////////////// @@ -1834,6 +1835,20 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; return n; } + var getPrefixForNamespaceNode = function (attrNode) { + var nm = String(attrNode.name); + + if (nm === "xmlns") { + return ""; + } + + if (nm.substring(0, 6) === "xmlns:") { + return nm.substring(6, nm.length); + } + + return null; + }; + PathExpr.applyStep = function (step, xpc, node) { var self = this; var newNodes = []; @@ -1976,30 +1991,30 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; break; case Step.NAMESPACE: - var n = {}; + var nodes = {}; + if (xpc.contextNode.nodeType == NodeTypes.ELEMENT_NODE) { - n["xml"] = XPath.XML_NAMESPACE_URI; - n["xmlns"] = XPath.XMLNS_NAMESPACE_URI; + // BUG: This only collects the namespaces on the current node, but seemingly + // it should collect all those in scope + nodes["xml"] = new XPathNamespace("xml", null, XPath.XML_NAMESPACE_URI, xpc.contextNode); + for (var m = xpc.contextNode; m != null && m.nodeType == NodeTypes.ELEMENT_NODE; m = m.parentNode) { for (var k = 0; k < m.attributes.length; k++) { var attr = m.attributes.item(k); - var nm = String(attr.name); - if (nm == "xmlns") { - if (n[""] == undefined) { - n[""] = attr.value; - } - } else if (nm.length > 6 && nm.substring(0, 6) == "xmlns:") { - var pre = nm.substring(6, nm.length); - if (n[pre] == undefined) { - n[pre] = attr.value; - } + + var pre = getPrefixForNamespaceNode(attr); + + if (pre != null && nodes[pre] == undefined) { + nodes[pre] = new XPathNamespace(pre, attr, attr.value, xpc.contextNode); } } } - for (var pre in n) { - var nsn = new XPathNamespace(pre, n[pre], xpc.contextNode); - if (step.nodeTest.matches(nsn, xpc)) { - newNodes.push(nsn); + + for (var pre in nodes) { + var node = nodes[pre]; + + if (step.nodeTest.matches(node, xpc)) { + newNodes.push(node); } } } @@ -2396,7 +2411,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; [ NodeTypes.ELEMENT_NODE, NodeTypes.ATTRIBUTE_NODE, - XPathNamespace.XPATH_NAMESPACE_NODE, + NodeTypes.NAMESPACE_NODE, ] )(n) && NodeTest.nameSpaceMatches(this.prefix, xpc, n) && @@ -2435,7 +2450,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; [ NodeTypes.ELEMENT_NODE, NodeTypes.ATTRIBUTE_NODE, - XPathNamespace.XPATH_NAMESPACE_NODE, + NodeTypes.NAMESPACE_NODE, ], '*' ); @@ -2458,8 +2473,8 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; NodeTest.NODE, [ NodeTypes.ELEMENT_NODE, - NodeTypes.ATTRIBUTE_NODE, - NodeTypes.TEXT_NODE, + NodeTypes.ATTRIBUTE_NODE, + NodeTypes.TEXT_NODE, NodeTypes.CDATA_SECTION_NODE, NodeTypes.PROCESSING_INSTRUCTION_NODE, NodeTypes.COMMENT_NODE, @@ -3099,8 +3114,8 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; n2Par = n2.parentNode || n2.ownerElement; } - var n1isAttr = Utilities.isAttribute(n1); - var n2isAttr = Utilities.isAttribute(n2); + var n1isAttr = isAttributeLike(n1); + var n2isAttr = isAttributeLike(n2); if (n1isAttr && !n2isAttr) { return -1; @@ -3109,15 +3124,35 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; return 1; } + // xml namespace node comes before others. namespace nodes before non-namespace nodes + if (n1.isXPathNamespace){ + if (n1.nodeValue === XPath.XML_NAMESPACE_URI) { + return -1; + } + + if (!n2.isXPathNamespace) { + return -1; + } + + if (n2.nodeValue === XPath.XML_NAMESPACE_URI) { + return 1; + } + } else if (n2.isXPathNamespace) { + return 1; + } + if (n1Par) { - var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes, - len = cn.length; + var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes; + var len = cn.length; + var n1Compare = n1.baseNode || n1; + var n2Compare = n2.baseNode || n2; + for (var i = 0; i < len; i += 1) { var n = cn[i]; - if (n === n1) { + if (n === n1Compare) { return -1; } - if (n === n2) { + if (n === n2Compare) { return 1; } } @@ -3388,16 +3423,17 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; XPathNamespace.prototype.constructor = XPathNamespace; XPathNamespace.superclass = Object.prototype; - function XPathNamespace(pre, ns, p) { + function XPathNamespace(pre, node, uri, p) { this.isXPathNamespace = true; + this.baseNode = node; this.ownerDocument = p.ownerDocument; this.nodeName = "#namespace"; this.prefix = pre; this.localName = pre; - this.namespaceURI = ns; - this.nodeValue = ns; + this.namespaceURI = uri; + this.nodeValue = uri; this.ownerElement = p; - this.nodeType = XPathNamespace.XPATH_NAMESPACE_NODE; + this.nodeType = NodeTypes.NAMESPACE_NODE; } XPathNamespace.prototype.toString = function () { @@ -3912,8 +3948,13 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; var Utilities = new Object(); - Utilities.isAttribute = function (val) { - return val && (val.nodeType === NodeTypes.ATTRIBUTE_NODE || val.ownerElement); + // Returns true if the node is an attribute node or namespace node + var isAttributeLike = function (val) { + return val && ( + val.nodeType === NodeTypes.ATTRIBUTE_NODE || + val.ownerElement || + val.isXPathNamespace + ); } Utilities.splitQName = function (qn) { From 4b030c458433c57d72e34034f3a64fa5ec2a669d Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 17:40:31 +0900 Subject: [PATCH 04/12] [135] Sort nodes before applying predicates --- test.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- xpath.js | 12 +++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/test.js b/test.js index 18ba6b8..16e3170 100644 --- a/test.js +++ b/test.js @@ -356,7 +356,17 @@ describe('xpath', () => { }); it('should correctly evaluate context position', () => { - var doc = parseXml("The boy who livedThe vanishing glassThe worst birthdayDobby's warningThe burrow"); + var doc = parseXml(` + + The boy who lived + The vanishing glass + + + The worst birthday + Dobby's warning + The burrow + + `); var chapters = xpath.parse('/books/book/chapter[2]').select({ node: doc }); @@ -379,6 +389,54 @@ describe('xpath', () => { assert.strictEqual(1, lastChapter.length); assert.strictEqual("The burrow", lastChapter[0].textContent); + + const blockQuotes = parseXml(` + +
+
+
+ + This is a test! + +
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+ + This is also a test! + +
+
+
+
+
+
+
+
+
+
+
+ + `); + + const x = xpath + .parse(`(.//*[local-name(.)='blockquote'])[not(@class="gmail_quote") and not(ancestor::*[local-name() = 'blockquote'])][last()]`) + .select({ node: blockQuotes }); + + assert.strictEqual(1, x.length); + + assert.strictEqual('This is also a test!', x[0].textContent.trim()); }); it('should select and sort namespace nodes properly', () => { diff --git a/xpath.js b/xpath.js index 180a629..af568fa 100644 --- a/xpath.js +++ b/xpath.js @@ -167,6 +167,16 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; var prototypeConcat = Array.prototype.concat; + var sortNodes = function(nodes, reverse) { + var ns = new XNodeSet(); + + ns.addArray(nodes); + + var sorted = ns.toArray(); + + return reverse ? sorted.reverse() : sorted; + } + // .apply() fails above a certain number of arguments - https://github.com/goto100/xpath/pull/98 var MAX_ARGUMENT_LENGTH = 32767; @@ -1805,7 +1815,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; inNodes ); }, - nodes, + sortNodes(nodes), predicates ); }; From 834cae6978906f2c24c5f00d8a43e75dd8ab3a6a Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 18:09:09 +0900 Subject: [PATCH 05/12] [135] Use correct node positions on reverse axes --- package.json | 1 + test.js | 75 ++++- xpath.js | 24 +- yarn.lock | 834 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 926 insertions(+), 8 deletions(-) create mode 100644 yarn.lock diff --git a/package.json b/package.json index 4053f5e..835799f 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "devDependencies": { "@xmldom/xmldom": "^0.8.9", "es-check": "^7.1.1", + "func-xml": "^0.0.10", "mocha": "^9.0.2" }, "typings": "./xpath.d.ts", diff --git a/test.js b/test.js index 16e3170..7919205 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,7 @@ +const { allChildEls } = require('func-xml'); const xpath = require('./xpath.js'); const dom = require('@xmldom/xmldom').DOMParser; -const assert = require('assert'); +const { strict: assert } = require('assert'); var xhtmlNs = 'http://www.w3.org/1999/xhtml'; @@ -461,6 +462,57 @@ describe('xpath', () => { assert.equal('http://publisher', namespaces[4].nodeValue); assert.equal('p', namespaces[4].localName); }); + + it('should respect reverse axes', () => { + const doc = parseXml(` + Chapter 1 + Chapter 2 + Chapter 3 + Chapter 4 + `) + + const [c1, c2, c3] = allChildEls(doc.documentElement); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding-sibling::*[1]').evaluateString({ node: doc }), + 'Chapter 3', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding-sibling::*[2]').evaluateString({ node: doc }), + 'Chapter 2', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding-sibling::*[3]').evaluateString({ node: doc }), + 'Chapter 1', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding-sibling::*[4]').evaluateString({ node: doc }), + '', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding-sibling::*[last()]').evaluateString({ node: doc }), + 'Chapter 1', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding::chapter[last()]').evaluateString({ node: doc }), + 'Chapter 1', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding::*[position() = 1]').evaluateString({ node: doc }), + 'Chapter 3', + ); + + assert.equal( + xpath.parse('/*/chapter[last()]/preceding::*[. != "Chapter 3"][1]').evaluateString({ node: doc }), + 'Chapter 2', + ); + }); }); describe('string()', () => { @@ -1046,7 +1098,11 @@ describe('xpath', () => { assert.strictEqual('Heyy', translated); - var characters = parseXml('HarryRonHermione'); + var characters = parseXml(` + Harry + Ron + Hermione + `); var firstTwo = xpath.parse('/characters/character[position() <= 2]').select({ node: characters }); @@ -1054,10 +1110,23 @@ describe('xpath', () => { assert.strictEqual('Harry', firstTwo[0].textContent); assert.strictEqual('Ron', firstTwo[1].textContent); - var last = xpath.parse('/characters/character[last()]').select({ node: characters }); + const last = xpath.parse('/characters/character[last()]').select({ node: characters }); assert.strictEqual(1, last.length); assert.strictEqual('Hermione', last[0].textContent); + + const lastPrefiltered = xpath.parse('/characters/character[. != "Hermione"][last()]').select({ node: characters }); + + assert.strictEqual(1, lastPrefiltered.length); + assert.strictEqual('Ron', lastPrefiltered[0].textContent); + + const lastStrict = xpath.parse('/characters/character[last() = 3]').select({ node: characters, }); + + assert.equal(3, lastStrict.length); + + const lastStrictMiss = xpath.parse('/characters/character[last() = 2]').select({ node: characters, }); + + assert.equal(0, lastStrictMiss.length); }); }); diff --git a/xpath.js b/xpath.js index af568fa..be94224 100644 --- a/xpath.js +++ b/xpath.js @@ -1794,7 +1794,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; return node; } - PathExpr.applyPredicates = function (predicates, c, nodes) { + var applyPredicates = function (predicates, c, nodes, reverse) { if (predicates.length === 0) { return nodes; } @@ -1815,7 +1815,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; inNodes ); }, - sortNodes(nodes), + sortNodes(nodes, reverse), predicates ); }; @@ -2094,10 +2094,11 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; }; function applyStepWithPredicates(step, xpc, node) { - return PathExpr.applyPredicates( + return applyPredicates( step.predicates, xpc, - PathExpr.applyStep(step, xpc, node) + PathExpr.applyStep(step, xpc, node), + includes(REVERSE_AXES, step.axis) ); } @@ -2134,7 +2135,12 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; } return { - nodes: PathExpr.applyPredicates(this.filterPredicates || [], xpc, ns.toUnsortedArray()) + nodes: applyPredicates( + this.filterPredicates || [], + xpc, + ns.toUnsortedArray(), + false // reverse + ) }; }; @@ -2314,6 +2320,14 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; [Step.SELF, 'self'] ]); + var REVERSE_AXES = [ + Step.ANCESTOR, + Step.ANCESTORORSELF, + Step.PARENT, + Step.PRECEDING, + Step.PRECEDINGSIBLING + ]; + // NodeTest ////////////////////////////////////////////////////////////////// NodeTest.prototype = new Object(); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..bbaa9a0 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,834 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + +"@dabh/diagnostics@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" + integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/triple-beam@^1.3.2": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" + integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@xmldom/xmldom@^0.8.9": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== + +acorn@8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +async@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + +commander@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.0.tgz#71797971162cd3cf65f0b9d24eb28f8d303acdf1" + integrity sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + +es-check@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/es-check/-/es-check-7.1.1.tgz#c2f8f609fd136d20e5047a4a185f80167e2498bf" + integrity sha512-rgwR2wdJp437Exq28Emwc4x5+Qn6ORDliN9daWo0wTCg5jOQxJsIZieqxVi4AfDEIN4OwMwYhld9b13mnRocUQ== + dependencies: + acorn "8.8.2" + commander "10.0.0" + fast-glob "^3.2.12" + supports-color "^8.1.1" + winston "^3.8.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +fast-glob@^3.2.12: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + 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" + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +func-xml@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/func-xml/-/func-xml-0.0.10.tgz#7409a439f0cdefba1ac23888501bc4077c531cdb" + integrity sha512-/t0Y/SN4BBBl1oBEJ8tgDqgdxWeiLDl+nuZkafpvRYCLiIKzY8Ouzu9sKwH1R5jYK3t5yc6UngTR8I0GjTbIbQ== + dependencies: + ramda "0.29.0" + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +logform@^2.3.2, logform@^2.4.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" + integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== + dependencies: + "@colors/colors" "1.6.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mocha@^9.0.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "4.2.1" + ms "2.1.3" + nanoid "3.3.1" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +ramda@0.29.0: + version "0.29.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.0.tgz#fbbb67a740a754c8a4cbb41e2a6e0eb8507f55fb" + integrity sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@^5.1.0, safe-buffer@~5.2.0: + 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-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +which@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +winston-transport@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.6.0.tgz#f1c1a665ad1b366df72199e27892721832a19e1b" + integrity sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + +winston@^3.8.2: + version "3.11.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.11.0.tgz#2d50b0a695a2758bb1c95279f0a88e858163ed91" + integrity sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g== + dependencies: + "@colors/colors" "^1.6.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.5.0" + +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 6250f52f2ede83555b0459f3efd36adee2a81933 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 18:25:08 +0900 Subject: [PATCH 06/12] -> 0.0.34 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 835799f..b500aa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xpath", - "version": "0.0.33", + "version": "0.0.34", "description": "DOM 3 XPath implemention and helper for node.js and the web", "engines": { "node": ">=0.6.0" From 71ab3ed273bb545fd4ff2bdcfb7eaac6bd679176 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 19:34:22 +0900 Subject: [PATCH 07/12] [83] Test string values obtained from namespace nodes --- test.js | 43 +++++++++++++++++++++++++++++++++++++++++-- xpath.js | 8 +++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/test.js b/test.js index 7919205..db1e78b 100644 --- a/test.js +++ b/test.js @@ -391,6 +391,7 @@ describe('xpath', () => { assert.strictEqual(1, lastChapter.length); assert.strictEqual("The burrow", lastChapter[0].textContent); + // #135 - issues with context position const blockQuotes = parseXml(`
@@ -441,6 +442,8 @@ describe('xpath', () => { }); it('should select and sort namespace nodes properly', () => { + // #83 + const doc = parseXml(''); const namespaces = xpath.parse('/*/namespace::*').select({ node: doc }); @@ -471,8 +474,6 @@ describe('xpath', () => { Chapter 4 `) - const [c1, c2, c3] = allChildEls(doc.documentElement); - assert.equal( xpath.parse('/*/chapter[last()]/preceding-sibling::*[1]').evaluateString({ node: doc }), 'Chapter 3', @@ -618,6 +619,44 @@ describe('xpath', () => { assert.strictEqual(str, 'e'); }); + + it('should get string values from namespace nodes', ()=> { + const doc = parseXml(''); + + assert.equal( + xpath.parse('string(/*/namespace::author)').evaluateString({ node: doc }), + 'http://author' + ); + assert.equal( + xpath.parse('name(/*/namespace::author)').evaluateString({ node: doc }), + 'author' + ); + assert.equal( + xpath.parse('local-name(/*/namespace::author)').evaluateString({ node: doc }), + 'author' + ); + assert.equal( + xpath.parse('namespace-uri(/*/namespace::author)').evaluateString({ node: doc }), + '' + ); + + assert.equal( + xpath.parse('string(/*/namespace::*[not(local-name())])').evaluateString({ node: doc }), + 'https://book' + ); + assert.equal( + xpath.parse('name(/*/namespace::*[not(local-name())])').evaluateString({ node: doc }), + '' + ); + assert.equal( + xpath.parse('local-name(/*/namespace::*[not(local-name())])').evaluateString({ node: doc }), + '' + ); + assert.equal( + xpath.parse('namespace-uri(/*/namespace::*[not(local-name())])').evaluateString({ node: doc }), + '' + ); + }); }); describe('parsed expressions', () => { diff --git a/xpath.js b/xpath.js index be94224..eaef6ff 100644 --- a/xpath.js +++ b/xpath.js @@ -3451,10 +3451,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; this.isXPathNamespace = true; this.baseNode = node; this.ownerDocument = p.ownerDocument; - this.nodeName = "#namespace"; + this.nodeName = pre; this.prefix = pre; this.localName = pre; - this.namespaceURI = uri; + this.namespaceURI = null; this.nodeValue = uri; this.ownerElement = p; this.nodeType = NodeTypes.NAMESPACE_NODE; @@ -3679,6 +3679,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; Functions.namespaceURI = function () { var c = arguments[0]; var n; + if (arguments.length == 1) { n = c.contextNode; } else if (arguments.length == 2) { @@ -3686,10 +3687,11 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; } else { throw new Error("Function namespace-uri expects (node-set?)"); } + if (n == null) { return new XString(""); } - return new XString(n.namespaceURI); + return new XString(n.namespaceURI || ''); }; Functions.name = function () { From a602158168192f197fcf9c2ce7d479b24e26e84e Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 20:04:02 +0900 Subject: [PATCH 08/12] [135] Node position tests --- test.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/test.js b/test.js index db1e78b..e05babc 100644 --- a/test.js +++ b/test.js @@ -466,6 +466,66 @@ describe('xpath', () => { assert.equal('p', namespaces[4].localName); }); + it('should allow using node positions', () => { + const doc = parseXml(` + + Chapter 1 + Chapter 2 + Chapter 3 + Chapter 4 + + + 1章 + 2章 + 3章 + 4章 + + `) + + assert.equal( + xpath.parse('/*/book/chapter[1]').evaluateString({ node: doc }), + 'Chapter 1', + ); + + assert.equal( + xpath.parse('/*/book/chapter[2]').evaluateString({ node: doc }), + 'Chapter 2', + ); + + assert.equal( + xpath.parse('/*/book/chapter[3]').evaluateString({ node: doc }), + 'Chapter 3', + ); + + assert.equal( + xpath.parse('/*/book[2]/chapter[1]').evaluateString({ node: doc }), + '1章', + ); + + assert.equal( + xpath.parse('/*/book/chapter[5]').evaluateString({ node: doc }), + '', + ); + + assert.equal( + xpath.parse('(/*/book/chapter)[5]').evaluateString({ node: doc }), + '1章', + ); + + const pos1Nodes = xpath.parse('/*/book/chapter[1]').select({ node: doc }); + + assert.equal(pos1Nodes.length, 2); + + assert.equal(pos1Nodes[0].textContent, 'Chapter 1'); + assert.equal(pos1Nodes[1].textContent, '1章'); + + const first3Nodes = xpath.parse('/*/book/chapter[position() <= 3]').select({ node: doc }); + + assert.equal(first3Nodes.length, 6); + + assert.equal(first3Nodes[5].textContent, '3章'); + }); + it('should respect reverse axes', () => { const doc = parseXml(` Chapter 1 @@ -620,7 +680,7 @@ describe('xpath', () => { assert.strictEqual(str, 'e'); }); - it('should get string values from namespace nodes', ()=> { + it('should get string values from namespace nodes', () => { const doc = parseXml(''); assert.equal( From d5bf3d98a57b49fb9e0c7e20e481c3f00a490505 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 20:58:24 +0900 Subject: [PATCH 09/12] Throw error if XPath expression unspecified --- test.js | 12 ++++++++++++ xpath.js | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/test.js b/test.js index e05babc..7bf3be0 100644 --- a/test.js +++ b/test.js @@ -1301,6 +1301,18 @@ describe('xpath', () => { }); }); + describe('error handling', () => { + it('should reject unspecified expression', () => { + for (let expr of [null, undefined, '']) { + assert.throws(() => { + xpath.parse(expr); + }, { + message: 'XPath expression unspecified' + }); + } + }); + }); + describe('Node type tests', () => { it('should correctly identify a Node of type Element', () => { var doc = parseXml(''); diff --git a/xpath.js b/xpath.js index eaef6ff..398e80c 100644 --- a/xpath.js +++ b/xpath.js @@ -1246,6 +1246,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; XPathParser.ACCEPT = 'a'; XPathParser.prototype.parse = function (s) { + if (!s) { + throw new Error('XPath expression unspecified'); + } + var types; var values; var res = this.tokenize(s); From 3ce4730fa6aa3e6169f62d7b60cc0c83387278a2 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 21:26:25 +0900 Subject: [PATCH 10/12] Validate nodes passed to XPath#evaluate() --- test.js | 10 ++++++++++ xpath.js | 54 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/test.js b/test.js index 7bf3be0..2580d74 100644 --- a/test.js +++ b/test.js @@ -1311,6 +1311,16 @@ describe('xpath', () => { }); } }); + + it('should reject non-nodes', () => { + for (let node of ['', 0, 45, true, false, [], {}]) { + assert.throws(() => { + xpath.parse('/*').select({ node }); + }, { + message: 'Context node does not appear to be a valid DOM node.' + }); + } + }); }); describe('Node type tests', () => { diff --git a/xpath.js b/xpath.js index 398e80c..17c0009 100644 --- a/xpath.js +++ b/xpath.js @@ -101,6 +101,28 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; (function (exports) { "use strict"; + // namespace nodes are not part of the DOM spec, so we use a custom nodetype for them. + // should NOT be used externally + var NAMESPACE_NODE_NODETYPE = '__namespace'; + + var isNil = function (x) { + return x === null || x === undefined; + }; + + var isValidNodeType = function (nodeType) { + return nodeType === NAMESPACE_NODE_NODETYPE || + (Number.isInteger(nodeType) + && nodeType >= 1 + && nodeType <= 11 + ); + }; + + var isNodeLike = function (value) { + return value + && isValidNodeType(value.nodeType) + && typeof value.nodeName === "string"; + }; + // functional helpers function curry(func) { var slice = Array.prototype.slice, @@ -167,7 +189,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; var prototypeConcat = Array.prototype.concat; - var sortNodes = function(nodes, reverse) { + var sortNodes = function (nodes, reverse) { var ns = new XNodeSet(); ns.addArray(nodes); @@ -221,7 +243,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, - NAMESPACE_NODE: '__namespace', // not part of DOM model + NAMESPACE_NODE: NAMESPACE_NODE_NODETYPE, }; // XPathParser /////////////////////////////////////////////////////////////// @@ -1328,6 +1350,12 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; } XPath.prototype.evaluate = function (c) { + var node = c.expressionContextNode; + + if (!(isNil(node) || isNodeLike(node))) { + throw new Error("Context node does not appear to be a valid DOM node."); + } + c.contextNode = c.expressionContextNode; c.contextSize = 1; c.contextPosition = 1; @@ -3153,7 +3181,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; } // xml namespace node comes before others. namespace nodes before non-namespace nodes - if (n1.isXPathNamespace){ + if (n1.isXPathNamespace) { if (n1.nodeValue === XPath.XML_NAMESPACE_URI) { return -1; } @@ -4494,6 +4522,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; this.context.caseInsensitive = XPathExpression.detectHtmlDom(n); var result = this.xpath.evaluate(this.context); + return new XPathResult(result, t); } @@ -4904,21 +4933,21 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; DivOperation: DivOperation, ModOperation: ModOperation, UnaryMinusOperation: UnaryMinusOperation, - + FunctionCall: FunctionCall, VariableReference: VariableReference, - + XPathContext: XPathContext, - + XNodeSet: XNodeSet, XBoolean: XBoolean, XString: XString, XNumber: XNumber, - + NamespaceResolver: NamespaceResolver, FunctionResolver: FunctionResolver, VariableResolver: VariableResolver, - + Utilities: Utilities, } ); @@ -4970,15 +4999,6 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; return exports.select(e, doc, true); }; - var isNodeLike = function (value) { - return value - && typeof value.nodeType === "number" - && Number.isInteger(value.nodeType) - && value.nodeType >= 1 - && value.nodeType <= 11 - && typeof value.nodeName === "string"; - }; - var isArrayOfNodes = function (value) { return Array.isArray(value) && value.every(isNodeLike); }; From 35dabde5698553a7e0a6882e98bfad288c967098 Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 22:22:12 +0900 Subject: [PATCH 11/12] Handle unspecified nodes --- test.js | 24 ++++++++++++++++-------- xpath.js | 13 +++++++++++-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/test.js b/test.js index 2580d74..dee7076 100644 --- a/test.js +++ b/test.js @@ -1304,23 +1304,31 @@ describe('xpath', () => { describe('error handling', () => { it('should reject unspecified expression', () => { for (let expr of [null, undefined, '']) { - assert.throws(() => { - xpath.parse(expr); - }, { - message: 'XPath expression unspecified' + assert.throws(() => xpath.parse(expr), { + message: 'XPath expression unspecified', }); } }); it('should reject non-nodes', () => { for (let node of ['', 0, 45, true, false, [], {}]) { - assert.throws(() => { - xpath.parse('/*').select({ node }); - }, { - message: 'Context node does not appear to be a valid DOM node.' + assert.throws(() => xpath.parse('/*').select({ node }), { + message: 'Context node does not appear to be a valid DOM node.', }); } }); + + it('should handle unspecified nodes', () => { + assert.throws( + () => xpath.parse('my:field').select(), { + message: 'Context node not found when evaluating XPath step: child::my:field', + }); + + assert.throws( + () => xpath.parse('/*').select(), { + message: 'Context node not found when determining document root.', + }); + }) }); describe('Node type tests', () => { diff --git a/xpath.js b/xpath.js index 17c0009..788faa8 100644 --- a/xpath.js +++ b/xpath.js @@ -1855,7 +1855,9 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; PathExpr.getRoot = function (xpc, nodes) { var firstNode = nodes[0]; - if (firstNode.nodeType === NodeTypes.DOCUMENT_NODE) { + // xpc.virtualRoot could possibly provide a root even if firstNode is null, + // so using a guard here instead of throwing. + if (firstNode && firstNode.nodeType === NodeTypes.DOCUMENT_NODE) { return firstNode; } @@ -1863,6 +1865,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; return xpc.virtualRoot; } + if (!firstNode) { + throw new Error('Context node not found when determining document root.'); + } + var ownerDoc = firstNode.ownerDocument; if (ownerDoc) { @@ -1892,7 +1898,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; }; PathExpr.applyStep = function (step, xpc, node) { - var self = this; + if (!node) { + throw new Error('Context node not found when evaluating XPath step: ' + step); + } + var newNodes = []; xpc.contextNode = node; From 62f02a16f2493f938996d2d849f6c62e7950f77f Mon Sep 17 00:00:00 2001 From: James Rishe Date: Sat, 16 Dec 2023 22:35:31 +0900 Subject: [PATCH 12/12] Reject non-string expressions --- test.js | 9 ++++++++- xpath.js | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/test.js b/test.js index dee7076..4fe9aaf 100644 --- a/test.js +++ b/test.js @@ -1305,11 +1305,18 @@ describe('xpath', () => { it('should reject unspecified expression', () => { for (let expr of [null, undefined, '']) { assert.throws(() => xpath.parse(expr), { - message: 'XPath expression unspecified', + message: 'XPath expression unspecified.', }); } }); + it('should reject non-string expression', () => { + for (let expr of [{}, []]) { + assert.throws(() => xpath.parse(expr), { + message: 'XPath expression must be a string.', + }); + } + }); it('should reject non-nodes', () => { for (let node of ['', 0, 45, true, false, [], {}]) { assert.throws(() => xpath.parse('/*').select({ node }), { diff --git a/xpath.js b/xpath.js index 788faa8..c3b298f 100644 --- a/xpath.js +++ b/xpath.js @@ -1269,7 +1269,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports; XPathParser.prototype.parse = function (s) { if (!s) { - throw new Error('XPath expression unspecified'); + throw new Error('XPath expression unspecified.'); + } + if (typeof s !== 'string'){ + throw new Error('XPath expression must be a string.'); } var types;