diff --git a/.eslintrc b/.eslintrc index 2723f19..93f1df6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -67,7 +67,7 @@ "es6": true }, "parserOptions": { - "ecmaVersion": 9, + "ecmaVersion": "latest", "sourceType": "module", "ecmaFeatures": { "jsx": true, diff --git a/.gitignore b/.gitignore index 91a2f79..7c1bba6 100644 --- a/.gitignore +++ b/.gitignore @@ -62,4 +62,7 @@ typings/ !.tmp/favicon.ico .cache -.dccache \ No newline at end of file +.dccache + +.yalc +yalc.lock \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 7147c5c..53d62a1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,11 @@ { - "deepcode.uploadApproved": true, - "cSpell.words": ["eqeqeq", "onbeforeupdate", "oncreate", "onremove"], - "prettier.trailingComma": "none" + "cSpell.words": [ + "eqeqeq", + "onbeforeupdate", + "oncleanup", + "oncreate", + "onremove" + ], + "prettier.trailingComma": "none", + "prettier.printWidth": 160 } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7606e07..1976c72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,16 @@ ### [5.0.17](https://github.com/Masquerade-Circus/valyrian.js/compare/5.0.16...5.0.17) (2021-12-17) - ### Performance Improvements -* **lib:** small performance improvements ([8f1ae1e](https://github.com/Masquerade-Circus/valyrian.js/commit/8f1ae1ed31d6fade49775f76180d4f480838e513)) - +* **lib:** small performance improvements ([8f1ae1e](https://github.com/Masquerade-Circus/valyrian.js/commit/8f1ae1ed31d6fade49775f76180d4f480838e513)) ### Tests -* update benchmarks ([eb403de](https://github.com/Masquerade-Circus/valyrian.js/commit/eb403de31678765d0b7d8dfce6add04a38ffd3dd)) - +* update benchmarks ([eb403de](https://github.com/Masquerade-Circus/valyrian.js/commit/eb403de31678765d0b7d8dfce6add04a38ffd3dd)) ### Build System -* update dependencies ([5c97e8d](https://github.com/Masquerade-Circus/valyrian.js/commit/5c97e8d83a73d1d864530e3357e7a4e6ca5c9212)) +* update dependencies ([5c97e8d](https://github.com/Masquerade-Circus/valyrian.js/commit/5c97e8d83a73d1d864530e3357e7a4e6ca5c9212)) ### [5.0.16](https://github.com/Masquerade-Circus/valyrian.js/compare/5.0.15...5.0.16) (2021-08-04) diff --git a/README.md b/README.md index 2bfebae..aab9613 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ ![](https://img.shields.io/github/issues/masquerade-circus/valyrian.js.svg) ![](https://img.shields.io/snyk/vulnerabilities/npm/valyrian.js.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/521f72fc6d61426783692b62d64a3643)](https://www.codacy.com/app/Masquerade-Circus/valyrian.js?utm_source=github.com\&utm_medium=referral\&utm_content=Masquerade-Circus/valyrian.js\&utm_campaign=Badge_Grade) -[![Maintainability](https://api.codeclimate.com/v1/badges/c1263dd7fb4f90194625/maintainability)](https://codeclimate.com/github/Masquerade-Circus/valyrian.js/maintainability) [![Coverage Status](https://coveralls.io/repos/github/Masquerade-Circus/valyrian.js/badge.svg?branch=master)](https://coveralls.io/github/Masquerade-Circus/valyrian.js?branch=master) [![License](https://img.shields.io/github/license/masquerade-circus/valyrian.js.svg)](https://github.com/masquerade-circus/valyrian.js/blob/master/LICENSE) diff --git a/bench/.bench-test.json b/bench/.bench-test.json deleted file mode 100644 index e896c13..0000000 --- a/bench/.bench-test.json +++ /dev/null @@ -1,286 +0,0 @@ -[ - { - "tag": "8f1ae1ed31d6fade49775f76180d4f480838e513", - "timestamp": "2021-08-10T18:14:29.637Z", - "suites": { - "Matching keyed list": { - "Removed at the end": { - "hz": 13843147.117343122, - "meanTime": 0.0000722379088745773, - "medianTime": 0.0000680088996887207, - "standardDeviation": 0.00042877065505546146, - "maxTime": 0.4502910077571869, - "minTime": 0.000059992074966430664 - } - }, - "Matching keyed list -> stress": { - "Removed at the end": { - "hz": 12422377.247000432, - "meanTime": 0.00008049988984527619, - "medianTime": 0.0000749826431274414, - "standardDeviation": 0.00027194826576966674, - "maxTime": 0.21449699997901917, - "minTime": 0.00006699562072753906 - } - }, - "hyperscript": { - "Valyrian 5.0.8": { - "hz": 11319013.434587948, - "meanTime": 0.00008834692226305354, - "medianTime": 0.00008299946784973145, - "standardDeviation": 0.0005409524513552643, - "maxTime": 0.40178897976875305, - "minTime": 0.00007399916648864746 - }, - "Valyrian next": { - "hz": 12375130.889701415, - "meanTime": 0.00008080722611444863, - "medianTime": 0.00007599592208862305, - "standardDeviation": 0.00037632133074474907, - "maxTime": 0.3384949862957001, - "minTime": 0.0000680088996887207 - } - }, - "Set.has vs [].indexOf": { - "Set.has": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "[].indexOf": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - } - }, - "Object.keys for loop vs Object.keys for of vs for in": { - "Object.keys for loop": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "Object.keys for of": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "for in": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - } - }, - "typeof function vs startsWith vs charAt vs string[0]": { - "typeof function": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "startsWith": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "charAt": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "string[0]": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - } - }, - "Array.isArray vs typeof object & Array.isArray": { - "Array.isArray": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - }, - "typeof object & Array.isArray": { - "hz": 0, - "meanTime": 0, - "medianTime": 0, - "standardDeviation": 0, - "maxTime": 0, - "minTime": 0 - } - }, - "Mount and update: Mount multiple types": { - "Valyrian 5.0.8": { - "hz": 2902.424855082848, - "meanTime": 0.344539497120402, - "medianTime": 0.3158630132675171, - "standardDeviation": 0.12547047831784758, - "maxTime": 3.329019993543625, - "minTime": 0.29217401146888733 - }, - "Valyrian next": { - "hz": 1955.2347882027263, - "meanTime": 0.5114475284675204, - "medianTime": 0.5008789896965027, - "standardDeviation": 0.10858653402744443, - "maxTime": 3.539449006319046, - "minTime": 0.42389801144599915 - } - }, - "Mount and update: Mount single text": { - "Valyrian 5.0.8": { - "hz": 563163.7564910672, - "meanTime": 0.0017756824519936268, - "medianTime": 0.0015400052070617676, - "standardDeviation": 0.008721908634331324, - "maxTime": 1.7687189877033234, - "minTime": 0.0013429820537567139 - }, - "Valyrian next": { - "hz": 588864.345468643, - "meanTime": 0.0016981839836204685, - "medianTime": 0.0014680027961730957, - "standardDeviation": 0.007901310872149805, - "maxTime": 0.9200059771537781, - "minTime": 0.0013020038604736328 - } - }, - "Mount and update: Update multiple types": { - "Valyrian 5.0.8": { - "hz": 191.46922053851156, - "meanTime": 5.222771561859797, - "medianTime": 5.1248679757118225, - "standardDeviation": 0.5295244468492879, - "maxTime": 11.35259997844696, - "minTime": 4.994443982839584 - }, - "Valyrian next": { - "hz": 988.9617184290813, - "meanTime": 1.0111614851871642, - "medianTime": 0.9874210059642792, - "standardDeviation": 0.17563506977385074, - "maxTime": 4.4599060118198395, - "minTime": 0.8580270111560822 - } - }, - "Mount and update: Update single text": { - "Valyrian 5.0.8": { - "hz": 281041.30071332253, - "meanTime": 0.0035581958860205196, - "medianTime": 0.003233999013900757, - "standardDeviation": 0.008330635728654796, - "maxTime": 2.148925006389618, - "minTime": 0.0029729902744293213 - }, - "Valyrian next": { - "hz": 303605.0335040786, - "meanTime": 0.0032937530332037995, - "medianTime": 0.0029140114784240723, - "standardDeviation": 0.010686156739409163, - "maxTime": 0.9253660142421722, - "minTime": 0.0026279985904693604 - } - }, - "Mount and update: Render list": { - "vOld": { - "hz": 32234.74893486094, - "meanTime": 0.031022422480186565, - "medianTime": 0.02816900610923767, - "standardDeviation": 0.028445183605242633, - "maxTime": 2.241923987865448, - "minTime": 0.026877999305725098 - }, - "VNext": { - "hz": 36094.39940924254, - "meanTime": 0.027705129226888708, - "medianTime": 0.024733006954193115, - "standardDeviation": 0.03313229161212847, - "maxTime": 3.294002026319504, - "minTime": 0.023487001657485962 - } - }, - "Mount and update: Render keyed list": { - "vOld": { - "hz": 10818.729602584868, - "meanTime": 0.09243229443141593, - "medianTime": 0.08125397562980652, - "standardDeviation": 0.0758776377704544, - "maxTime": 4.654555976390839, - "minTime": 0.07728502154350281 - }, - "VNext": { - "hz": 10520.295372507426, - "meanTime": 0.09505436535682156, - "medianTime": 0.08138898015022278, - "standardDeviation": 0.08801408887318905, - "maxTime": 4.140509992837906, - "minTime": 0.07600200176239014 - } - }, - "Mount and update: Render keyed list -> stress": { - "vOld": { - "hz": 5912.339869909631, - "meanTime": 0.1691377732003226, - "medianTime": 0.1536639928817749, - "standardDeviation": 0.07667175327766867, - "maxTime": 1.6021479964256287, - "minTime": 0.14648601412773132 - }, - "VNext": { - "hz": 6223.138379681636, - "meanTime": 0.16069062569217016, - "medianTime": 0.14509502053260803, - "standardDeviation": 0.07779315135447662, - "maxTime": 1.1707000136375427, - "minTime": 0.1383270025253296 - } - }, - "Mount and update: Render keyed list -> swap keys on large set": { - "vOld": { - "hz": 956.5646051100083, - "meanTime": 1.0454076961011918, - "medianTime": 0.899418979883194, - "standardDeviation": 0.3488216147974813, - "maxTime": 4.253165006637573, - "minTime": 0.8360439836978912 - }, - "VNext": { - "hz": 1088.780339822946, - "meanTime": 0.9184589061946297, - "medianTime": 0.8092609941959381, - "standardDeviation": 0.276212975273171, - "maxTime": 2.6908140182495117, - "minTime": 0.7434589862823486 - } - } - } - } -] \ No newline at end of file diff --git a/bench/.buffalo-test.json b/bench/.buffalo-test.json index 490390e..7a0cf40 100644 --- a/bench/.buffalo-test.json +++ b/bench/.buffalo-test.json @@ -1,44 +1,24 @@ [ { - "tag": "8f1ae1ed31d6fade49775f76180d4f480838e513", - "timestamp": "2021-12-17T00:06:41.419Z", + "tag": "cc572c7a35f8702f51103a2c6bbf4c0ba8a2d49d", + "timestamp": "2022-03-11T15:30:14.026Z", "suites": { - "Matching keyed list": { - "Removed at the end": { - "hz": 16671904.491364745, - "meanTime": 0.000059981149755143596, - "medianTime": 0.000056996941566467285, - "standardDeviation": 0.00021825156804251554, - "maxTime": 0.33727000281214714, - "minTime": 0.000048998743295669556 - } - }, - "Matching keyed list -> stress": { - "Removed at the end": { - "hz": 15985997.638615083, - "meanTime": 0.00006255474463379397, - "medianTime": 0.000059001147747039795, - "standardDeviation": 0.0001994548743399828, - "maxTime": 0.17909200116991997, - "minTime": 0.00004999712109565735 - } - }, "hyperscript": { "Valyrian 5.0.8": { - "hz": 13456357.953304552, - "meanTime": 0.00007431431323914986, - "medianTime": 0.00006800144910812378, - "standardDeviation": 0.000290168848348955, - "maxTime": 0.2560419999063015, - "minTime": 0.00005999952554702759 + "hz": 1080326.7077752561, + "meanTime": 0.0009256459113737224, + "medianTime": 0.000880001112818718, + "standardDeviation": 0.0019245132562002675, + "maxTime": 1.0293420013040304, + "minTime": 0.0008110012859106064 }, "Valyrian next": { - "hz": 16580133.323220424, - "meanTime": 0.00006031314589005766, - "medianTime": 0.00005700066685676575, - "standardDeviation": 0.0002683531202565282, - "maxTime": 0.3098529987037182, - "minTime": 0.00005000084638595581 + "hz": 16115471.232596528, + "meanTime": 0.0000620521724476362, + "medianTime": 0.00005799904465675354, + "standardDeviation": 0.0003135987904997287, + "maxTime": 0.38400099985301495, + "minTime": 0.000048998743295669556 } }, "Set.has vs [].indexOf": { @@ -137,148 +117,382 @@ "minTime": 0 } }, + "string comparison vs instance comparison vs property comparison": { + "string comparison": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "instance comparison": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "property comparison": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "property string comparison": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "typeof comparison": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + } + }, + "Object with property equals true vs set vs map vs string array": { + "Object with property equals true": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "key in object": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "set": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "map": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "string array": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + } + }, + "For loop if/continue vs if/else": { + "for loop if/continue": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "for loop if/else": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + } + }, + "map array of strings vs reduce with object keys equals index": { + "map array of strings": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "reduce with object keys equals index": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "array by for": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "object by for": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "object map by for": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + } + }, + "Symbol access vs direct access": { + "Direct access access": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + }, + "Symbol access access": { + "hz": 0, + "meanTime": 0, + "medianTime": 0, + "standardDeviation": 0, + "maxTime": 0, + "minTime": 0 + } + }, "Mount and update: Mount multiple types": { "Valyrian 5.0.8": { - "hz": 3035.107184017302, - "meanTime": 0.3294776557697672, - "medianTime": 0.3060449995100498, - "standardDeviation": 0.11670815968939321, - "maxTime": 3.5715750008821487, - "minTime": 0.28655700013041496 + "hz": 231.12463957243787, + "meanTime": 4.326669808333374, + "medianTime": 3.8601179998368025, + "standardDeviation": 0.9841018665650515, + "maxTime": 16.50512699969113, + "minTime": 3.4267710000276566 }, "Valyrian next": { - "hz": 1995.8871120056313, - "meanTime": 0.5010303408368211, - "medianTime": 0.490922998636961, - "standardDeviation": 0.11500613641370512, - "maxTime": 3.1317549981176853, - "minTime": 0.41110100224614143 + "hz": 190.72752224077007, + "meanTime": 5.243081796750984, + "medianTime": 4.557700000703335, + "standardDeviation": 1.4485380371450673, + "maxTime": 21.492678999900818, + "minTime": 4.197591999545693 } }, "Mount and update: Mount single text": { "Valyrian 5.0.8": { - "hz": 574020.7897105797, - "meanTime": 0.001742097181713921, - "medianTime": 0.0015110000967979431, - "standardDeviation": 0.00871027385649084, - "maxTime": 1.0047080032527447, - "minTime": 0.00136600062251091 + "hz": 308291.664552809, + "meanTime": 0.0032436816008325924, + "medianTime": 0.002925001084804535, + "standardDeviation": 0.009799869368766293, + "maxTime": 2.0299989990890026, + "minTime": 0.002689000219106674 + }, + "Valyrian next": { + "hz": 991469.4670056179, + "meanTime": 0.0010086039290954118, + "medianTime": 0.0008969996124505997, + "standardDeviation": 0.004353378616590844, + "maxTime": 1.675339998677373, + "minTime": 0.0007819999009370804 + } + }, + "Mount and update: Mount single text in div": { + "Valyrian 5.0.8": { + "hz": 230963.46085280567, + "meanTime": 0.0043296891911284, + "medianTime": 0.004048001021146774, + "standardDeviation": 0.007079474560488834, + "maxTime": 0.8394400011748075, + "minTime": 0.0038300007581710815 }, "Valyrian next": { - "hz": 670298.460656875, - "meanTime": 0.0014918727383321543, - "medianTime": 0.0012869983911514282, - "standardDeviation": 0.008272256863081372, - "maxTime": 1.5173600018024445, - "minTime": 0.001189999282360077 + "hz": 622554.7973912942, + "meanTime": 0.0016062843049163274, + "medianTime": 0.0014120005071163177, + "standardDeviation": 0.007555544120265702, + "maxTime": 4.195627000182867, + "minTime": 0.001238001510500908 } }, "Mount and update: Update multiple types": { "Valyrian 5.0.8": { - "hz": 189.34742908870902, - "meanTime": 5.2812969513914085, - "medianTime": 5.137601997703314, - "standardDeviation": 0.5869414447582827, - "maxTime": 10.952287998050451, - "minTime": 4.94692900031805 + "hz": 137.8959353535325, + "meanTime": 7.251845367568209, + "medianTime": 6.874644000083208, + "standardDeviation": 1.056586388734975, + "maxTime": 28.21982100047171, + "minTime": 6.408681999891996 }, "Valyrian next": { - "hz": 1015.6718063437537, - "meanTime": 0.9845700094795684, - "medianTime": 0.958076000213623, - "standardDeviation": 0.16159128266950185, - "maxTime": 3.7391529977321625, - "minTime": 0.8335059992969036 + "hz": 84.54008104717887, + "meanTime": 11.828708792483118, + "medianTime": 11.467360999435186, + "standardDeviation": 1.1468001569640918, + "maxTime": 25.269207000732422, + "minTime": 10.522560000419617 } }, "Mount and update: Update single text": { "Valyrian 5.0.8": { - "hz": 270212.40386823955, - "meanTime": 0.003700792360692731, - "medianTime": 0.0033080019056797028, - "standardDeviation": 0.012645737126902255, - "maxTime": 2.229399997740984, - "minTime": 0.003110002726316452 + "hz": 120376.38304877312, + "meanTime": 0.00830727734687649, + "medianTime": 0.007910998538136482, + "standardDeviation": 0.007917335864379938, + "maxTime": 2.3376929983496666, + "minTime": 0.007453998550772667 }, "Valyrian next": { - "hz": 303415.56365041697, - "meanTime": 0.0032958098390501785, - "medianTime": 0.0028010010719299316, - "standardDeviation": 0.015595430114341434, - "maxTime": 1.4865939989686012, - "minTime": 0.0026200003921985626 + "hz": 587749.2525940249, + "meanTime": 0.0017014058215923048, + "medianTime": 0.0014800000935792923, + "standardDeviation": 0.006738557866547813, + "maxTime": 0.9990600012242794, + "minTime": 0.001343999058008194 } }, "Mount and update: Render list": { "vOld": { - "hz": 30695.202025360184, - "meanTime": 0.03257838144130168, - "medianTime": 0.02901199832558632, - "standardDeviation": 0.043461287312234656, - "maxTime": 2.0518620014190674, - "minTime": 0.02764499932527542 + "hz": 8372.462761654158, + "meanTime": 0.11943916962879732, + "medianTime": 0.11290699988603592, + "standardDeviation": 0.040672784902507815, + "maxTime": 2.5568989999592304, + "minTime": 0.10850599966943264 }, "VNext": { - "hz": 34264.97096268492, - "meanTime": 0.02918432357899895, - "medianTime": 0.02490699663758278, - "standardDeviation": 0.044102742115498944, - "maxTime": 3.1514320001006126, - "minTime": 0.02388399839401245 + "hz": 32843.46647722804, + "meanTime": 0.030447455986211087, + "medianTime": 0.027370000258088112, + "standardDeviation": 0.033472306541327115, + "maxTime": 3.8741210009902716, + "minTime": 0.024598998948931694 } }, "Mount and update: Render keyed list": { "vOld": { - "hz": 10720.337430113585, - "meanTime": 0.09328064592360548, - "medianTime": 0.08023500069975853, - "standardDeviation": 0.0861680625592031, - "maxTime": 3.6683319993317127, - "minTime": 0.0776359997689724 + "hz": 3184.865886451974, + "meanTime": 0.3139849637794409, + "medianTime": 0.29534799978137016, + "standardDeviation": 0.11912784123862281, + "maxTime": 3.687518000602722, + "minTime": 0.26649999991059303 }, "VNext": { - "hz": 11728.004767713635, - "meanTime": 0.08526599535096789, - "medianTime": 0.07374100014567375, - "standardDeviation": 0.07861224431554834, - "maxTime": 3.2908590026199818, - "minTime": 0.07119200006127357 + "hz": 9117.675382791396, + "meanTime": 0.10967707864302664, + "medianTime": 0.0962739996612072, + "standardDeviation": 0.09252007605668011, + "maxTime": 3.1177280005067587, + "minTime": 0.08741600066423416 } }, "Mount and update: Render keyed list -> stress": { "vOld": { - "hz": 5617.286997486036, - "meanTime": 0.17802188146120015, - "medianTime": 0.15422199666500092, - "standardDeviation": 0.12149204821686695, - "maxTime": 3.3464059978723526, - "minTime": 0.14767500013113022 + "hz": 1710.918236731253, + "meanTime": 0.5844814664612624, + "medianTime": 0.5567669998854399, + "standardDeviation": 0.19120539283918606, + "maxTime": 2.271033000200987, + "minTime": 0.49701100029051304 }, "VNext": { - "hz": 5506.425278112736, - "meanTime": 0.18160602378004817, - "medianTime": 0.1479550004005432, - "standardDeviation": 0.17073753397126684, - "maxTime": 6.763663999736309, - "minTime": 0.13728399947285652 + "hz": 4725.658694760313, + "meanTime": 0.21161071177416468, + "medianTime": 0.1804379988461733, + "standardDeviation": 0.3219729930676698, + "maxTime": 46.89825800061226, + "minTime": 0.16306399926543236 } }, "Mount and update: Render keyed list -> swap keys on large set": { "vOld": { - "hz": 924.5032237385955, - "meanTime": 1.081661993514856, - "medianTime": 0.9031809978187084, - "standardDeviation": 0.4723178336406087, - "maxTime": 6.736775998026133, - "minTime": 0.7774330005049706 + "hz": 310.0796208804964, + "meanTime": 3.2249781432279176, + "medianTime": 2.9686950016766787, + "standardDeviation": 1.007842372830396, + "maxTime": 20.209640000015497, + "minTime": 2.839145001024008 }, "VNext": { - "hz": 1035.442356229234, - "meanTime": 0.9657708070217406, - "medianTime": 0.8098049983382225, - "standardDeviation": 0.40682233960256786, - "maxTime": 3.912805996835232, - "minTime": 0.7240439988672733 + "hz": 781.1533956129919, + "meanTime": 1.2801582962015718, + "medianTime": 1.1108550000935793, + "standardDeviation": 0.709011674133977, + "maxTime": 22.38246599957347, + "minTime": 0.9737960007041693 + } + }, + "Mount and update: Update class": { + "vOld update": { + "hz": 982.8274054593915, + "meanTime": 1.0174726451920433, + "medianTime": 0.9915020000189543, + "standardDeviation": 0.1735599056885286, + "maxTime": 5.256726000458002, + "minTime": 0.8852149993181229 + }, + "VNext update": { + "hz": 4136.14385283788, + "meanTime": 0.24177108813898787, + "medianTime": 0.2136400006711483, + "standardDeviation": 0.14183725449488108, + "maxTime": 5.079613000154495, + "minTime": 0.18483399972319603 + } + }, + "Mount and update: Update class with hooks vs shouldupdate property": { + "shouldupdate property": { + "hz": 4305.22836471938, + "meanTime": 0.23227571577731654, + "medianTime": 0.20516799949109554, + "standardDeviation": 0.1395912633754471, + "maxTime": 4.750409999862313, + "minTime": 0.178294001147151 + }, + "useMemo hook": { + "hz": 2022.8663221151528, + "meanTime": 0.4943480392487717, + "medianTime": 0.4481320008635521, + "standardDeviation": 0.28033136821875804, + "maxTime": 14.368340998888016, + "minTime": 0.38005900010466576 + } + }, + "Lifecycle vs hooks": { + "Hooks": { + "hz": 312912.4994451379, + "meanTime": 0.0031957815739966223, + "medianTime": 0.0026869997382164, + "standardDeviation": 0.01864210814178492, + "maxTime": 14.44373599998653, + "minTime": 0.0024319998919963837 + }, + "Lifecycle": { + "hz": 355303.66081815877, + "meanTime": 0.0028144939393455644, + "medianTime": 0.0024609994143247604, + "standardDeviation": 0.010571937974029605, + "maxTime": 1.3473349995911121, + "minTime": 0.0021550003439188004 } } } diff --git a/bench/equalize_arrays.test.js b/bench/equalize_arrays.test.js deleted file mode 100644 index 17dca48..0000000 --- a/bench/equalize_arrays.test.js +++ /dev/null @@ -1,263 +0,0 @@ -/* eslint-disable eqeqeq */ -let { compare, benchmark, before } = require("buffalo-test"); -let expect = require("expect"); - -type Set = number[]; - -type Movement = { - key: number, - currentIndex: number, - indexInNewKeyedListArray: number, - indexInOldKeyedListArray: number, - oldKeyedListBeforeMovement: Set, - oldKeyedListAfterMovement: Set, - newKeyedList: Set -}; - -let getCurrentLineInCode = () => { - let error = new Error(); - let stack = error.stack.split("\n"); - return stack[2]; -}; - -// Para igualar las listas de elementos, -// 1. Se deben mover los elementos de la lista anterior para igualarla a la lista nueva -// 2. Se debe obtener el máximo de longitud de las listas -// 3. Ciclar sobre toda la lista de elementos hasta el máximo de longitud -// 3.1. Si el indice actual es mayor a la longitud de la lista nueva todos los elementos restantes de la lista anterior se deben eliminar -// 3.1.1 Eliminar todos los elementos restantes de la lista anterior -// 3.1.2. Como ya eliminamos todos los elementos restantes entonces ya no necesitamos proseguir más y terminamos el ciclo -// 3.2. Si el indice actual es mayor a la longitud de la lista anterior el nuevo elemento se tiene que agregar -// 3.3. Si el nuevo elemento es diferente al elemento de la lista anterior entonces tenemos una operación de movimiento -// 3.3.1. Debemos tomar el nuevo elemento de la lista nueva en la posición del indice actual -// 3.3.2. Buscar el nuevo elemento en la lista anterior -// 3.3.3. Se debe mover el nuevo elemento a la posición del indice actual -// 3.3.4. Si el nuevo elemento está en la lista nueva, tomarlo (quitarlo) de su posición actual en la lista anterior -// 3.3.5. Buscar el antiguo elemento en la lista nueva para decidir si podemos reemplazarlo o insertar el nuevo elemento antes del antiguo elemento -// 3.3.6. Si el antiguo elemento no está en la lista nueva, eliminarlo de la lista anterior reemplazandolo con el nuevo elemento -// 3.3.7. Si el antiguo elemento está en la lista nueva, se debe mover el nuevo elemento antes del antiguo elemento -// 3.4. Si los elementos son iguales no necesitamos hacer nada - -function matchKeyedList(oldKeyedList: Set, newKeyedList: Set): Movement[] { - // 1. Se deben mover los elementos de la lista anterior para igualarla a la lista nueva - let movements: Movement[] = []; - - // 2. Se debe obtener el máximo de longitud de las listas - const oldListLength = oldKeyedList.length; - const newListLength = newKeyedList.length; - const maxListLength = Math.max(oldListLength, newListLength); - - // 3. Ciclar sobre toda la lista de elementos hasta el máximo de longitud - for (let i = 0; i < maxListLength; i++) { - // 3.1. Si el indice actual es mayor a la longitud de la lista nueva todos los elementos restantes de la lista anterior se deben eliminar - if (i >= newListLength) { - // 3.1.1 Eliminar todos los elementos restantes de la lista anterior - for (let k = oldKeyedList.length - 1; k > newListLength - 1; k--) { - let movement = { - key: k, - currentIndex: k, - indexInNewKeyedListArray: -1, - indexInOldKeyedListArray: k, - oldKeyedListBeforeMovement: [...oldKeyedList], - newKeyedList: newKeyedList, - line: getCurrentLineInCode(), - operation: "remove" - }; - - oldKeyedList.pop(); - movement.oldKeyedListAfterMovement = [...oldKeyedList]; - movements.push(movement); - } - - // 3.1.2. Como ya eliminamos todos los elementos restantes entonces ya no necesitamos proseguir más y terminamos el ciclo - break; - } - - // 3.2. Si el indice actual es mayor a la longitud de la lista anterior el nuevo elemento se tiene que agregar - if (i >= oldKeyedList.length) { - let movement = { - key: newKeyedList[i], - currentIndex: i, - indexInNewKeyedListArray: i, - indexInOldKeyedListArray: -1, - oldKeyedListBeforeMovement: [...oldKeyedList], - newKeyedList: newKeyedList, - operation: "add", - line: getCurrentLineInCode() - }; - - oldKeyedList.push(newKeyedList[i]); - movement.oldKeyedListAfterMovement = [...oldKeyedList]; - movements.push(movement); - - continue; - } - - let newKey = newKeyedList[i]; - let oldKey = oldKeyedList[i]; - - // 3.3. Si el nuevo elemento es diferente al elemento de la lista anterior entonces tenemos una operación de movimiento - if (newKey !== oldKey) { - // 3.3.1. Debemos tomar el nuevo elemento de la lista nueva en la posición del indice actual - // 3.3.2. Buscar el nuevo elemento en la lista anterior - const oldIndex = oldKeyedList.indexOf(newKey); - - let movement = { - key: newKey, - currentIndex: i, - indexInNewKeyedListArray: i, - indexInOldKeyedListArray: oldIndex, - oldKeyedListBeforeMovement: [...oldKeyedList], - newKeyedList: newKeyedList - }; - - // 3.3.3. Si el nuevo elemento está en la lista nueva, tomarlo (quitarlo) de su posición actual en la lista anterior - oldIndex !== -1 && oldKeyedList.splice(oldIndex, 1); - - // 3.3.4. Buscar el antiguo elemento en la lista nueva para decidir si podemos reemplazarlo o insertar el nuevo elemento antes del antiguo elemento - const oldKeyIndexInNewKeyedList = newKeyedList.indexOf(oldKeyedList[i]); - - // 3.3.5. Si el antiguo elemento no está en la lista nueva, eliminarlo de la lista anterior reemplazandolo con el nuevo elemento - if (oldKeyIndexInNewKeyedList === -1) { - movement.line = getCurrentLineInCode(); - movement.operation = "replace"; - oldKeyedList.splice(i, 1, newKey); - movement.oldKeyedListAfterMovement = [...oldKeyedList]; - movements.push(movement); - continue; - } - - // 3.3.6. Si el antiguo elemento está en la lista nueva, se debe mover el nuevo elemento antes del antiguo elemento - movement.line = getCurrentLineInCode(); - movement.operation = "move"; - oldKeyedList.splice(i, oldKeyIndexInNewKeyedList !== i + 1 ? 1 : 0, newKey); - movement.oldKeyedListAfterMovement = [...oldKeyedList]; - movements.push(movement); - - // 3.3.7. if the old element is in the new list then move the old element to the new position - if (oldKeyIndexInNewKeyedList !== i + 1) { - movement = { - key: oldKey, - currentIndex: i, - indexInNewKeyedListArray: oldKeyIndexInNewKeyedList, - indexInOldKeyedListArray: i, - oldKeyedListBeforeMovement: [...oldKeyedList], - newKeyedList: newKeyedList, - line: getCurrentLineInCode(), - operation: "move" - }; - oldKeyedList.splice(oldKeyIndexInNewKeyedList, 0, oldKey); - movement.oldKeyedListAfterMovement = [...oldKeyedList]; - movements.push(movement); - } - } - - // 3.4. Si los elementos son iguales no necesitamos hacer nada - } - return movements; -} - -compare("Matching keyed list", () => { - let set = [1, 2, 3, 4, 5]; - let tests = [ - { name: "Removed at the end", set: [1, 2, 3, 4], movements: 1 }, // Removed at the end - { name: "Removed at the start", set: [2, 3, 4, 5], movements: 1 }, // Remmoved at the start - { name: "Removed at the center", set: [1, 3, 5], movements: 2 }, // Removed at the center - { name: "Added at the end", set: [1, 2, 3, 4, 5, 6], movements: 1 }, // Added at the end - { name: "Added at the start", set: [6, 1, 2, 3, 4, 5], movements: 1 }, // Added at the start - { name: "Added at the center", set: [1, 2, 6, 3, 4, 5], movements: 1 }, // Added at the center - { name: "Reversed", set: [5, 4, 3, 2, 1], movements: 4 }, // Reversed - { name: "Switch positions", set: [5, 2, 3, 4, 1], movements: 2 }, // Switch positions, - { name: "Mixed positions", set: [1, 3, 2, 6, 5, 4], movements: 3 }, - { name: "Replaced with undefined", set: [1, 3, 2, 5, 4], movements: 2 }, - { - name: "Added, remove and replaced with undefined", - set: [6, 7, 8, 9, 10], - movements: 5 - }, - { name: "Removed all at the end", set: [1], movements: 4 } // Removed at the end - ]; - - before(() => { - for (let test of tests) { - test.oldSet = [...set]; - } - - // let oldKeyedList = [3, 6, 4, 8]; - // let newKeyedList = [4, 6, 8, 3]; - // console.log(oldKeyedList); - // console.log(newKeyedList); - // console.log(equalizeArrays([...oldKeyedList], newKeyedList)); - // console.log(calculateMovements([...oldKeyedList], newKeyedList)); - // console.log("-------------------"); - - function logMatchFromTest(test) { - let movements = matchKeyedList([...set], test.set); - console.log(test.name, movements, test.set); - expect(movements[movements.length - 1].oldKeyedListAfterMovement).toEqual(test.set); - expect(movements.length).toEqual(test.movements); - } - - // logMatchFromTest(tests[0]); - for (let test of tests) { - logMatchFromTest(test); - } - }); - - benchmark(tests[0].name, () => { - tests[0].oldSet = set; - }); -}); - -compare("Matching keyed list -> stress", () => { - let set = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let tests = [ - { name: "Removed at the end", set: [1, 2, 3, 4, 5, 6, 7, 8, 9], movements: 1 }, // Removed at the end - { name: "Removed at the start", set: [2, 3, 4, 5, 6, 7, 8, 9, 10], movements: 1 }, // Remmoved at the start - { name: "Removed at the center", set: [1, 2, 3, 5, 6, 8, 9, 10], movements: 2 }, // Removed at the center - { name: "Added at the end", set: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], movements: 1 }, // Added at the end - { name: "Added at the start", set: [11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], movements: 1 }, // Added at the start - { name: "Added at the center", set: [1, 2, 3, 4, 5, 11, 6, 7, 8, 9, 10], movements: 1 }, // Added at the center - { name: "Reversed", set: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1], movements: 9 }, // Reversed - { name: "Switch positions", set: [10, 2, 3, 4, 5, 6, 7, 8, 9, 1], movements: 2 }, // Switch positions, - { name: "Switch different positions", set: [10, 6, 3, 4, 2, 5, 7, 8, 9, 1], movements: 4 }, // Switch positions, - { name: "Mixed positions", set: [1, 3, 2, 6, 5, 4, 7, 8, 9, 10], movements: 3 }, - { name: "Replaced with undefined", set: [1, 3, 2, 5, 4, 6, 7, 8, 9, 10], movements: 2 }, - { - name: "Added, remove and replaced with undefined", - set: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], - movements: 10 - }, - { name: "Removed all at the end", set: [1], movements: 9 } // Removed at the end - ]; - - before(() => { - for (let test of tests) { - test.oldSet = [...set]; - } - - // let oldKeyedList = [3, 6, 4, 8]; - // let newKeyedList = [4, 6, 8, 3]; - // console.log(oldKeyedList); - // console.log(newKeyedList); - // console.log(equalizeArrays([...oldKeyedList], newKeyedList)); - // console.log(calculateMovements([...oldKeyedList], newKeyedList)); - // console.log("-------------------"); - - function logMatchFromTest(test) { - let movements = matchKeyedList([...set], test.set); - console.log(test.name, movements, test.set); - expect(movements[movements.length - 1].oldKeyedListAfterMovement).toEqual(test.set); - expect(movements.length).toEqual(test.movements); - } - - // logMatchFromTest(tests[0]); - for (let test of tests) { - logMatchFromTest(test); - } - }); - - benchmark(tests[0].name, () => { - tests[0].oldSet = set; - }); -}); diff --git a/bench/hyperscript.test.js b/bench/hyperscript_bench.js similarity index 54% rename from bench/hyperscript.test.js rename to bench/hyperscript_bench.js index 09061c0..f892bd3 100644 --- a/bench/hyperscript.test.js +++ b/bench/hyperscript_bench.js @@ -1,27 +1,17 @@ -let { compare, benchmark, before } = require("buffalo-test"); +const { before, benchmark, compare } = require("buffalo-test"); -import "../lib/index.ts"; - -import expect from "expect"; -import fs from "fs"; -import nodePlugin from "../plugins/node"; -import vOld from "./index-old"; - -let VNext = v; - -VNext.usePlugin(nodePlugin); +const { v: VNext } = require("../lib/index.ts"); +const expect = require("expect"); +const nodePlugin = require("../plugins/node"); +const { v: vOld } = require("./index-old.ts"); compare("hyperscript", () => { let date = new Date(); before(async () => { - VNext.inline.extensions("ts"); - await VNext.inline.ts("./lib/index.ts", { compact: true }); - await VNext.inline.js("./bench/index-old.js", { compact: true }); - console.log(VNext.inline.ts()[0].raw.length); - console.log(VNext.inline.js()[0].raw.length); - - let compiled = fs.readFileSync("./dist/valyrian.min.js", "utf8"); - console.log(compiled.length); + let { raw: newTs } = await nodePlugin.inline("./lib/index.ts", { compact: true, bundle: false }); + let { raw: oldjs } = await nodePlugin.inline("./bench/index-old.ts", { compact: true, bundle: false }); + console.log(oldjs.length); + console.log(newTs.length); expect(vOld("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]])).toEqual({ name: "div", @@ -29,7 +19,7 @@ compare("hyperscript", () => { children: [[null, "Hello", undefined, 1, date, { hello: "world" }, ["Hello"]]] }); expect(VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]])).toEqual({ - name: "div", + tag: "div", props: {}, children: [[null, "Hello", undefined, 1, date, { hello: "world" }, ["Hello"]]] }); diff --git a/bench/index-old.js b/bench/index-old.js deleted file mode 100644 index 5263fa1..0000000 --- a/bench/index-old.js +++ /dev/null @@ -1,461 +0,0 @@ -function Vnode(name, props, children) { - this.props = props || {}; - this.children = children; - this.name = name; -} - -function TextVnode(dom) { - this.dom = dom; -} - -function Component(component, props, children) { - this.props = props; - this.children = children; - this.component = component; -} - -function POJOComponent(component, props, children) { - this.props = props; - this.children = children; - this.component = component; -} - -const isArray = Array.isArray; -const UND = void 0; -const emptyNode = new Vnode("empty", null, []); -const createElement = (tag, isSVG = false) => (isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag)); - -//eslint-disable-next-line max-lines-per-function -function valyrian() { - let oncreate = "oncreate"; - let onupdate = "onupdate"; - let onremove = "onremove"; - let onbeforeupdate = "onbeforeupdate"; - let functionstr = "function"; - let once = "v-once"; - let mainNode; - let oldMainNode; - let mountedComponent; - let directives = {}; - let mainContainer; - - let lifecycleCall = (vnode, methodName, oldNode) => { - if (vnode.props[methodName]) { - return vnode.props[methodName](vnode, oldNode); - } - }; - - let callRemove = (vnode) => { - if (vnode instanceof Vnode) { - for (let i = 0, l = vnode.children.length; i < l; i++) { - callRemove(vnode.children[i]); - } - - vnode.props[onremove] && vnode.props[onremove](vnode); - } - }; - - function v(tagOrComponent, props, ...children) { - if (typeof tagOrComponent === "string") { - return new Vnode(tagOrComponent, props, children); - } - if ("view" in tagOrComponent) { - return new POJOComponent(tagOrComponent, props, children); - } - return new Component(tagOrComponent, props, children); - } - - // eslint-disable-next-line no-new-func - v.isNode = new Function("try {return this===global;}catch(e){return false;}")(); - - // Hydrates the current dom before mount - v.domToVnode = (dom) => { - if (dom.nodeType === 3) { - return new TextVnode(dom); - } - - if (dom.nodeType === 1) { - let props = {}; - [].forEach.call(dom.attributes, (prop) => (props[prop.nodeName] = prop.nodeValue)); - - let vnode = new Vnode(dom.nodeName, props, []); - vnode.dom = dom; - - for (let i = 0, l = dom.childNodes.length; i < l; i++) { - let childVnode = v.domToVnode(dom.childNodes[i]); - childVnode && vnode.children.push(childVnode); - } - return vnode; - } - }; - - v.trust = (htmlString) => { - let div = createElement("div"); - div.innerHTML = htmlString.trim(); - - return [].map.call(div.childNodes, (item) => v.domToVnode(item)); - }; - - // Plugin system - let plugins = new Map(); - v.usePlugin = (plugin, options) => !plugins.has(plugin) && plugins.set(plugin, true) && plugin(v, options); - const reservedWords = ["key", once, oncreate, onbeforeupdate, onupdate, onremove, "data"]; - v.reservedWords = reservedWords; - - let attachedListeners = {}; - function eventListener(e) { - let dom = e.target; - let name = `__on${e.type}`; - while (dom) { - if (dom[name]) { - dom[name](e, dom); - if (!e.defaultPrevented) { - v.update(); - } - return; - } - dom = dom.parentNode; - } - } - - const addProps = (newNode) => { - for (let name in newNode.props) { - let value = newNode.props[name]; - if (reservedWords.indexOf(name) !== -1) { - if (directives[name]) { - directives[name](value, newNode); - } - } else if (typeof value === "function") { - name = `__${name}`; - if (!attachedListeners[name]) { - mainContainer.addEventListener(name.slice(4), eventListener); - attachedListeners[name] = true; - } - newNode.dom[name] = value; - } else if (!newNode.isSVG && name in newNode.dom) { - if (newNode.dom[name] != value) { - newNode.dom[name] = value; - } - } else { - newNode.dom.setAttribute(name, value); - } - } - }; - - const updateProperty = (name, newNode, oldNode) => { - if (name in newNode.props) { - let value = newNode.props[name]; - if (reservedWords.indexOf(name) !== -1) { - if (directives[name]) { - directives[name](value, newNode, oldNode); - } - } else if (typeof value === functionstr) { - name = `__${name}`; - if (!attachedListeners[name]) { - mainContainer.addEventListener(name.slice(4), eventListener); - attachedListeners[name] = true; - } - newNode.dom[name] = value; - } else if (name in newNode.dom && !newNode.isSVG) { - if (newNode.dom[name] !== value) { - newNode.dom[name] = value; - } - } else if (!oldNode || value !== oldNode.props[name]) { - newNode.dom.setAttribute(name, value); - } - } - }; - - v.updateProperty = updateProperty; - - const updateProps = (newNode, oldNode) => { - for (let name in newNode.props) { - updateProperty(name, newNode, oldNode); - } - }; - - let removeProps = (newNode, oldNode) => { - for (let name in oldNode.props) { - if (reservedWords.indexOf(name) === -1 && name in newNode.props === false && typeof oldNode.props[name] !== functionstr) { - if (name in newNode.dom) { - newNode.dom[name] = UND; - } else { - newNode.dom.removeAttribute(name); - } - } - } - }; - - let moveDom = (dom, $parent, oldDom) => { - if (dom !== oldDom) { - oldDom ? $parent.replaceChild(dom, oldDom) : $parent.appendChild(dom); - } - }; - - let removeVnode = (vnode) => { - callRemove(vnode); - vnode.dom && vnode.dom.parentNode && vnode.dom.parentNode.removeChild(vnode.dom); - }; - - let updateKeyedNode = ($parent, newNode, newIndex, compareNode) => { - let oldDom = $parent.childNodes[newIndex]; - // Moved or updated - if (compareNode) { - newNode.dom = compareNode.dom; - if (once in newNode.props || lifecycleCall(newNode, onbeforeupdate, compareNode) === false) { - newNode.children = compareNode.children; - moveDom(newNode.dom, $parent, oldDom); - } else { - removeProps(newNode, compareNode); - updateProps(newNode, compareNode); - moveDom(newNode.dom, $parent, oldDom); - lifecycleCall(newNode, v.isMounted ? onupdate : oncreate, compareNode); - patch(newNode, compareNode); - } - } else { - newNode.dom = createElement(newNode.name, newNode.isSVG); - addProps(newNode); - moveDom(newNode.dom, $parent, oldDom); - lifecycleCall(newNode, oncreate); - patch(newNode); - } - }; - - let vnodesToCleanup = []; - - v.onCleanup = (callback) => { - let parentVnode = v.current.parentVnode; - if (!parentVnode.onCleanup) { - parentVnode.onCleanup = []; - } - - parentVnode.onCleanup.push(callback); - - if (vnodesToCleanup.indexOf(parentVnode) === -1) { - vnodesToCleanup.push(parentVnode); - } - }; - - let cleanupVnodes = () => { - for (let l = vnodesToCleanup.length; l--; ) { - for (let callback of vnodesToCleanup[l].onCleanup) { - callback(); - } - } - vnodesToCleanup = []; - }; - - const current = { - parentVnode: UND, - oldParentVnode: UND, - component: UND - }; - - v.current = current; - - // eslint-disable-next-line complexity,sonarjs/cognitive-complexity - let patch = (parentNode, oldParentNode = emptyNode) => { - let newTree = isArray(parentNode.children) ? parentNode.children : [parentNode.children]; - let oldTree = oldParentNode.children; - current.parentVnode = parentNode; - current.oldParentVnode = oldParentNode; - - // Flatten children - for (let i = 0; i < newTree.length; i++) { - let childVnode = newTree[i]; - - if (childVnode instanceof Vnode) { - childVnode.isSVG = parentNode.isSVG || childVnode.name === "svg"; - } else if (childVnode === null || childVnode === UND) { - newTree.splice(i--, 1); - } else if (childVnode instanceof Component) { - current.component = childVnode; - newTree.splice(i--, 1, childVnode.component.call(childVnode.component, childVnode.props, ...childVnode.children)); - } else if (childVnode instanceof POJOComponent) { - current.component = childVnode; - newTree.splice(i--, 1, childVnode.component.view.call(childVnode.component, childVnode.props, ...childVnode.children)); - } else if (isArray(childVnode)) { - newTree.splice(i--, 1, ...childVnode); - } - } - - if (newTree.length === 0) { - if (oldTree.length > 0) { - for (let i = oldTree.length; i--; ) { - callRemove(oldTree[i]); - } - parentNode.dom.textContent = ""; - } - - // Is keyed list - } else if (oldTree.length && newTree[0] instanceof Vnode && "key" in newTree[0].props) { - let oldKeys = oldTree.map((vnode) => vnode.props.key); - let newKeys = newTree.map((vnode) => vnode.props.key); - - for (let i = 0, l = newKeys.length; i < l; i++) { - let key = newKeys[i]; - let newNode = newTree[i]; - - // Updated: Same key - if (key === oldKeys[i]) { - oldTree[i].processed = true; - updateKeyedNode(parentNode.dom, newNode, i, oldTree[i]); - } else { - let oldIndex = oldKeys.indexOf(key); - let newIndex = i >= oldKeys.length ? UND : i; - - // Moved: Key exists in old keys - if (oldIndex !== -1) { - oldTree[oldIndex].processed = true; - updateKeyedNode(parentNode.dom, newNode, newIndex, oldTree[oldIndex]); - // Added: Key does not exists in old keys - } else { - updateKeyedNode(parentNode.dom, newNode, newIndex); - } - } - } - - // Delete unprocessed old keys - let l = oldTree.length; - - while (l--) { - !oldTree[l].processed && removeVnode(oldTree[l]); - } - - // Not keyed list or first render so use the simple algorithm - } else { - let i = oldTree.length; - let l = newTree.length; - - // Remove deleted nodes - while (i-- > l) { - removeVnode(oldTree[i]); - } - - for (i = 0; i < l; i++) { - let newNode = newTree[i]; - let oldNode = oldTree[i]; - // Is vnode - if (newNode instanceof Vnode) { - if (oldNode && newNode.name === oldNode.name) { - newNode.dom = oldNode.dom; - if (once in newNode.props || lifecycleCall(newNode, onbeforeupdate, oldNode) === false) { - newNode.children = oldNode.children; - } else { - removeProps(newNode, oldNode); - updateProps(newNode, oldNode); - lifecycleCall(newNode, v.isMounted ? onupdate : oncreate, oldNode); - patch(newNode, oldNode); - } - } else { - newNode.dom = createElement(newNode.name, newNode.isSVG); - addProps(newNode); - if (oldNode) { - callRemove(oldNode); - parentNode.dom.replaceChild(newNode.dom, parentNode.dom.childNodes[i]); - } else { - parentNode.dom.appendChild(newNode.dom); - } - lifecycleCall(newNode, oncreate); - patch(newNode); - } - } else { - let dom; - // If we are getting a TextVnode could be from the domToVnode method - let value = newNode instanceof TextVnode ? newNode.dom.nodeValue : String(newNode); - if (oldNode instanceof TextVnode) { - dom = oldNode.dom; - if (value != dom.nodeValue) { - dom.nodeValue = value; - } - } else { - dom = document.createTextNode(value); - if (oldNode) { - callRemove(oldNode); - parentNode.dom.replaceChild(dom, oldNode.dom); - } else { - parentNode.dom.appendChild(dom); - } - } - newTree[i] = new TextVnode(dom); - } - } - } - - parentNode.children = newTree; - }; - - v.update = (props, ...children) => { - if (mainNode) { - if (mountedComponent) { - cleanupVnodes(); - oldMainNode = mainNode; - mainNode = new Vnode(mainNode.name, mainNode.props, [v(mountedComponent, props, ...children)]); - mainNode.dom = oldMainNode.dom; - mainNode.isSVG = mainNode.name === "svg"; - patch(mainNode, oldMainNode); - v.isMounted = true; - } - - return v.isNode && mainNode.dom.innerHTML; - } - }; - - v.mount = (container, component, props, ...children) => { - mainContainer = v.isNode ? createElement("div") : typeof container === "string" ? document.querySelectorAll(container)[0] : container; - - mainNode = v.domToVnode(mainContainer); - mountedComponent = component; - - return v.update(props, ...children); - }; - - v.unMount = () => { - mainContainer = null; - mountedComponent = () => ""; - let result = v.update(); - v.isMounted = false; - return result; - }; - - v.directive = (directive, handler) => { - let directiveName = `v-${directive}`; - if (v.reservedWords.indexOf(directiveName) === -1) { - v.reservedWords.push(directiveName); - directives[directiveName] = handler; - } - }; - - let hideDirective = (test) => (bool, vnode, oldnode) => { - let value = test ? bool : !bool; - if (value) { - let newdom = document.createTextNode(""); - if (oldnode && oldnode.dom && oldnode.dom.parentNode) { - callRemove(oldnode); - oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); - } - vnode.name = ""; - vnode.children = []; - vnode.props = {}; - vnode.dom = newdom; - } - }; - - v.directive("if", hideDirective(false)); - v.directive("unless", hideDirective(true)); - v.directive("for", (set, vnode) => (vnode.children = set.map(vnode.children[0]))); - v.directive("show", (bool, vnode) => (vnode.dom.style.display = bool ? "" : "none")); - v.directive("class", (classes, vnode) => { - for (let name in classes) { - vnode.dom.classList.toggle(name, classes[name]); - } - }); - v.directive("html", (html, vnode) => (vnode.children = v.trust(html))); - v.newInstance = valyrian; - - return v; -} - -const v = valyrian(); - -module.exports = v; diff --git a/bench/index-old.ts b/bench/index-old.ts new file mode 100644 index 0000000..72024f4 --- /dev/null +++ b/bench/index-old.ts @@ -0,0 +1,566 @@ +/* eslint-disable complexity */ +/* eslint-disable sonarjs/cognitive-complexity */ +/* eslint-disable no-use-before-define */ +/* eslint-disable no-unused-vars */ + +// version 5.0.17 + +type VnodeOrUnknown = VnodeComponent | Vnode | TextVnode | any; + +type DomAttribute = { nodeName: string; nodeValue: string }; + +type DomElement = (HTMLElement | SVGElement) & Record; + +type Props = { + key?: string | number; + data?: string; + oncreate?: { (vnode: Vnode): never }; + onupdate?: { (vnode: Vnode, oldVnode: Vnode | TextVnode): never }; + onremove?: { (oldVnode: Vnode): never }; + onbeforeupdate?: { (vnode: Vnode, oldVnode: Vnode | TextVnode): undefined | boolean }; +} & Record; + +type Component = (props?: Record | null, children?: VnodeOrUnknown) => VnodeOrUnknown | VnodeOrUnknown[]; + +type ValyrianComponent = + | Component + | (Record & { + view: Component; + }); + +type Current = { parentVnode?: Vnode; oldParentVnode?: Vnode; component?: VnodeComponent }; + +interface Plugin { + (v: Valyrian, options?: Record): never; +} + +interface Directive { + (value: any, vnode: Vnode, oldVnode?: Vnode | TextVnode): void | boolean; +} + +interface ValyrianEventHandler { + (a: Event, dom: DomElement): void; +} + +interface Vnode { + name: string; + props: Props; + children: VnodeOrUnknown[]; + dom?: DomElement; + onCleanup?: FunctionConstructor[]; + isSVG?: boolean; + processed?: boolean; +} + +class Vnode implements Vnode { + name: string; + props: Props; + children: VnodeOrUnknown[]; + dom?: DomElement; + onCleanup?: FunctionConstructor[]; + isSVG?: boolean; + processed?: boolean; + + constructor(name: string, props: Props, children: VnodeOrUnknown) { + this.props = props; + this.children = children; + this.name = name; + } +} + +interface TextVnode { + dom?: Text; + nodeValue: string; +} + +class TextVnode implements TextVnode { + dom?: Text; + nodeValue: string; + + constructor(nodeValue: string) { + this.nodeValue = nodeValue; + } +} + +interface VnodeComponent { + component: ValyrianComponent; + props: Props; + children: VnodeOrUnknown[]; +} + +class VnodeComponent implements VnodeComponent { + component: ValyrianComponent; + props: Props; + children: VnodeOrUnknown[]; + + constructor(component: ValyrianComponent, props: Props, children: VnodeOrUnknown[]) { + this.props = props; + this.children = children; + this.component = component; + } +} + +interface Valyrian { + (tagOrComponent: string | ValyrianComponent, props?: Props | null, children?: VnodeOrUnknown): Vnode | VnodeComponent; + fragment: (props: Props, children: VnodeOrUnknown[]) => VnodeOrUnknown[]; + isMounted: boolean; + isNode: boolean; + reservedWords: string[]; + current: Current; + trust: (htmlString: string) => Vnode[]; + usePlugin: (plugin: Plugin, options: Record) => void; + onCleanup: (callback: typeof Function) => void; + updateProperty: (name: string, newVnode: Vnode & { dom: DomElement }, oldNode: Vnode & { dom: DomElement }) => void; + update: (props?: Props | null, ...children: VnodeOrUnknown) => string | void; + mount: (container: string | DomElement, component: ValyrianComponent, props?: Props | null, ...children: VnodeOrUnknown[]) => string | void; + unMount: () => string | boolean | void; + directive: (directive: string, handler: Directive) => void; + newInstance: () => Valyrian; + [x: string]: any; +} + +let isNode = typeof window === "undefined" || typeof global !== "undefined"; + +// Create Node element +function createElement(tagName: string, isSVG: boolean = false): DomElement { + return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName); +} + +// Transforms a DOM node to a VNode +function domToVnode(dom: DomElement): Vnode { + let props: Props = {}; + [].forEach.call(dom.attributes, (prop: Attr) => (props[prop.nodeName] = prop.nodeValue)); + + let vnode: Vnode = new Vnode(dom.nodeName.toLowerCase(), props, []); + vnode.dom = dom; + + for (let i = 0, l = dom.childNodes.length; i < l; i++) { + if (dom.childNodes[i].nodeType === 1) { + vnode.children.push(domToVnode(dom.childNodes[i] as DomElement)); + } else if (dom.childNodes[i].nodeType === 3) { + let textVnode = new TextVnode(dom.childNodes[i].nodeValue || ""); + textVnode.dom = dom.childNodes[i] as unknown as Text; + vnode.children.push(textVnode); + } + } + return vnode; +} + +const trust = (htmlString: string) => { + let div = createElement("div"); + div.innerHTML = htmlString.trim(); + + return [].map.call(div.childNodes, (item) => domToVnode(item)) as Vnode[]; +}; + +// eslint-disable-next-line max-lines-per-function +function valyrian(): Valyrian { + const v: Valyrian = (tagOrComponent, props, ...children) => { + if (typeof tagOrComponent === "string") { + return new Vnode(tagOrComponent, props || {}, children); + } else { + return new VnodeComponent(tagOrComponent, props || {}, children); + } + }; + + v.fragment = (props: Props, vnodes: VnodeOrUnknown[]) => { + return vnodes; + }; + + v.isMounted = false; + v.isNode = isNode; + const reservedWords = ["key", "data", "v-once", "oncreate", "onupdate", "onremove", "onbeforeupdate"]; + v.reservedWords = reservedWords; + v.trust = trust; + + const current: Current = { + parentVnode: undefined, + oldParentVnode: undefined, + component: undefined + }; + v.current = current; + + const plugins = new Map(); + + v.usePlugin = (plugin: Plugin, options: Record = {}) => !plugins.has(plugin) && plugins.set(plugin, true) && plugin(v as Valyrian, options); + + let vnodesToCleanup: Vnode[] = []; + + v.onCleanup = (callback: FunctionConstructor) => { + let parentVnode = v.current.parentVnode as Vnode; + if (!parentVnode.onCleanup) { + parentVnode.onCleanup = [] as FunctionConstructor[]; + } + + parentVnode.onCleanup.push(callback); + + if (vnodesToCleanup.indexOf(parentVnode) === -1) { + vnodesToCleanup.push(parentVnode); + } + }; + + let cleanupVnodes = () => { + for (let l = vnodesToCleanup.length; l--; ) { + for (let callback of vnodesToCleanup[l].onCleanup as FunctionConstructor[]) { + callback(); + } + } + vnodesToCleanup = []; + }; + + let mainContainer: DomElement | null = null; + let emptyComponent: ValyrianComponent = () => ""; + let mountedComponent: ValyrianComponent = emptyComponent; + + const attachedListeners: string[] = []; + function eventListener(e: Event) { + let dom = e.target as DomElement; + let name = `v-on${e.type}`; + while (dom) { + if (dom[name]) { + (dom[name] as ValyrianEventHandler)(e, dom); + if (!e.defaultPrevented) { + v.update(); + } + return; + } + dom = dom.parentNode as DomElement; + } + } + + function updateProperty(prop: string, newVnode: Vnode & { dom: DomElement }, oldVnode?: Vnode): void | boolean { + if (reservedWords.indexOf(prop) !== -1) { + if (prop in directives) { + return directives[prop](newVnode.props[prop], newVnode, oldVnode); + } + } else if (typeof newVnode.props[prop] === "function") { + if (attachedListeners.indexOf(prop) === -1) { + (mainContainer as DomElement).addEventListener(prop.slice(2), eventListener); + attachedListeners.push(prop); + } + newVnode.dom[`v-${prop}`] = newVnode.props[prop]; + } else if (prop in newVnode.dom && !newVnode.isSVG) { + // eslint-disable-next-line eqeqeq + if (newVnode.dom[prop] != newVnode.props[prop]) { + newVnode.dom[prop] = newVnode.props[prop]; + } + } else if (oldVnode === undefined || newVnode.props[prop] !== oldVnode.props[prop]) { + if (newVnode.props[prop] === false) { + newVnode.dom.removeAttribute(prop); + } else { + newVnode.dom.setAttribute(prop, newVnode.props[prop]); + } + } + } + v.updateProperty = updateProperty; + + // Update a Vnode.dom HTMLElement with new Vnode props that are different from old Vnode props + function updateProperties(newVnode: Vnode & { dom: DomElement }, oldVnode?: Vnode): void { + for (let prop in newVnode.props) { + if (updateProperty(prop, newVnode, oldVnode) === false) { + return; + } + } + } + + function removeProperties(newVnode: Vnode & { dom: DomElement }, oldVnode: Vnode) { + for (let name in oldVnode.props) { + if (name in newVnode.props === false && typeof oldVnode.props[name] !== "function" && reservedWords.indexOf(name) === -1) { + if (name in newVnode.dom) { + newVnode.dom[name] = null; + } else { + newVnode.dom.removeAttribute(name); + } + } + } + } + + const callRemove = (vnode: Vnode) => { + for (let i = 0, l = vnode.children.length; i < l; i++) { + vnode.children[i] instanceof Vnode && callRemove(vnode.children[i]); + } + + vnode.props.onremove && vnode.props.onremove(vnode); + }; + // Patch a DOM node with a new VNode tree + function patch(newParentVnode: Vnode & { dom: DomElement }, oldParentVnode?: Vnode & { dom: DomElement }): void { + let oldTree = oldParentVnode?.children || []; + let newTree = newParentVnode.children; + let oldTreeLength = oldTree.length; + + current.parentVnode = newParentVnode; + current.oldParentVnode = oldParentVnode; + + // Flat newTree + for (let i = 0; i < newTree.length; i++) { + let childVnode = newTree[i]; + + if (childVnode instanceof Vnode) { + childVnode.isSVG = newParentVnode.isSVG || childVnode.name === "svg"; + } else if (childVnode === null || childVnode === undefined) { + newTree.splice(i--, 1); + } else if (Array.isArray(childVnode)) { + newTree.splice(i--, 1, ...childVnode); + } else if (childVnode instanceof VnodeComponent) { + v.current.component = childVnode; + newTree.splice( + i--, + 1, + ...[ + "view" in childVnode.component + ? childVnode.component.view.call(childVnode.component, childVnode.props, childVnode.children) + : (childVnode.component as Component).call(childVnode.component, childVnode.props, childVnode.children) + ] + ); + } else { + if (i > 0 && newTree[i - 1].nodeValue) { + newTree[i - 1].nodeValue += childVnode; + newTree.splice(i--, 1); + } else if (childVnode instanceof TextVnode === false) { + newTree[i] = new TextVnode(String(childVnode)); + } + } + } + + let newTreeLength = newTree.length; + + // if newTree is empty, remove it + if (newTreeLength === 0) { + if (oldTreeLength > 0) { + for (let i = oldTreeLength; i--; ) { + oldTree[i] instanceof Vnode && callRemove(oldTree[i]); + } + // Fast node remove by setting textContent + newParentVnode.dom.textContent = ""; + } + // If the tree is keyed list and is not first render + } else if (oldTreeLength && newTree[0] instanceof Vnode && "key" in newTree[0].props) { + // 1. Mutate the old key list to match the new key list + let oldKeyedList; + + // if the oldTree does not have a keyed list fast remove all nodes + if (oldTree[0] instanceof Vnode === false || "key" in oldTree[0].props === false) { + for (let i = oldTreeLength; i--; ) { + oldTree[i] instanceof Vnode && callRemove(oldTree[i]); + } + // Fast node remove by setting textContent + newParentVnode.dom.textContent = ""; + oldKeyedList = []; + } else { + oldKeyedList = oldTree.map((vnode) => vnode.props.key); + } + + // 2. Obtain the max length of both lists + let newKeyedList = newTree.map((vnode) => vnode.props.key); + const maxListLength = Math.max(newTreeLength, oldKeyedList.length); + + // 3. Cycle over all the elements of the list until the max length + for (let i = 0; i < maxListLength; i++) { + if (i < newTreeLength) { + let childVnode = newTree[i]; + let oldChildVnode = oldKeyedList[i] === newKeyedList[i] ? oldTree[i] : oldTree[oldKeyedList.indexOf(childVnode.props.key)]; + let shouldPatch = true; + + if (oldChildVnode) { + childVnode.dom = oldChildVnode.dom; + oldChildVnode.processed = true; + if ("v-once" in childVnode.props || (childVnode.props.onbeforeupdate && childVnode.props.onbeforeupdate(childVnode, oldChildVnode) === false)) { + // skip this patch + childVnode.children = oldChildVnode.children; + shouldPatch = false; + } else { + removeProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + updateProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + if (v.isMounted) { + childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); + } else { + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + } + } else { + childVnode.dom = createElement(childVnode.name, childVnode.isSVG); + updateProperties(childVnode as Vnode & { dom: DomElement }); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + + if (newParentVnode.dom.childNodes[i] === undefined) { + newParentVnode.dom.appendChild(childVnode.dom); + } else if (newParentVnode.dom.childNodes[i] !== childVnode.dom) { + oldTree[i] instanceof Vnode && !oldTree[i].processed && newKeyedList.indexOf(oldTree[i].props.key) === -1 && callRemove(oldTree[i]); + newParentVnode.dom.replaceChild(childVnode.dom, newParentVnode.dom.childNodes[i]); + } + + shouldPatch && patch(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + } else { + if (!oldTree[i].processed) { + oldTree[i] instanceof Vnode && callRemove(oldTree[i]); + oldTree[i].dom.parentNode && newParentVnode.dom.removeChild(oldTree[i].dom); + } + } + } + } else { + for (let i = 0; i < newTreeLength; i++) { + let childVnode = newTree[i]; + let oldChildVnode = oldTree[i]; + + // if oldChildVnode is undefined, it's a new node, append it + if (oldChildVnode === undefined) { + if (childVnode instanceof Vnode) { + childVnode.dom = createElement(childVnode.name, childVnode.isSVG); + updateProperties(childVnode as Vnode & { dom: DomElement }); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + patch(childVnode as Vnode & { dom: DomElement }); + } else { + childVnode.dom = document.createTextNode(childVnode.nodeValue); + } + newParentVnode.dom.appendChild(childVnode.dom); + } else { + // if childVnode is Vnode, replace it with its DOM node + if (childVnode instanceof Vnode) { + if (childVnode.name === oldChildVnode.name) { + childVnode.dom = oldChildVnode.dom; + + if ("v-once" in childVnode.props || (childVnode.props.onbeforeupdate && childVnode.props.onbeforeupdate(childVnode, oldChildVnode) === false)) { + // skip this patch + childVnode.children = oldChildVnode.children; + continue; + } + + removeProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + updateProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + if (v.isMounted) { + childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); + } else { + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + patch(childVnode as Vnode & { dom: DomElement }, oldChildVnode); + } else { + childVnode.dom = createElement(childVnode.name, childVnode.isSVG); + updateProperties(childVnode as Vnode & { dom: DomElement }); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + oldChildVnode instanceof Vnode && callRemove(oldChildVnode); + newParentVnode.dom.replaceChild(childVnode.dom, oldChildVnode.dom); + patch(childVnode as Vnode & { dom: DomElement }); + } + } else { + if (oldChildVnode instanceof Vnode) { + childVnode.dom = document.createTextNode(childVnode.nodeValue); + callRemove(oldChildVnode); + newParentVnode.dom.replaceChild(childVnode.dom, oldChildVnode.dom as DomElement); + } else { + childVnode.dom = oldChildVnode.dom; + // eslint-disable-next-line eqeqeq + if (childVnode.nodeValue != childVnode.dom.nodeValue) { + childVnode.dom.nodeValue = childVnode.nodeValue; + } + } + } + } + } + + // For remaining old children: remove from DOM, garbage collect + for (let i = oldTreeLength - 1; i >= newTreeLength; --i) { + oldTree[i] instanceof Vnode && callRemove(oldTree[i]); + oldTree[i].dom.parentNode && newParentVnode.dom.removeChild(oldTree[i].dom); + } + } + + newParentVnode.children = newTree; + } + + let mainVnode: Vnode | null = null; + let oldMainVnode: Vnode | null = null; + + v.unMount = () => { + mountedComponent = emptyComponent; + let result = v.update(); + v.isMounted = false; + mainContainer = null; + return result; + }; + + v.update = (props, ...children) => { + if (mainVnode) { + cleanupVnodes(); + oldMainVnode = mainVnode; + mainVnode = new Vnode(mainVnode.name, mainVnode.props, [v(mountedComponent, props, ...children)]); + mainVnode.dom = oldMainVnode.dom; + mainVnode.isSVG = oldMainVnode.isSVG; + patch(mainVnode as Vnode & { dom: Node }, oldMainVnode as Vnode & { dom: Node }); + v.isMounted = true; + if (v.isNode) { + return (mainVnode.dom as HTMLElement).innerHTML; + } + } + }; + + v.mount = (container, component, props, ...children) => { + if (v.isMounted) { + v.unMount(); + } + + if (isNode) { + mainContainer = typeof container === "string" ? createElement(container, container === "svg") : container; + } else { + mainContainer = typeof container === "string" ? (document.querySelectorAll(container)[0] as DomElement) : container; + } + + if (mainContainer !== null) { + mainVnode = domToVnode(mainContainer); + mainVnode.isSVG = mainVnode.name === "svg"; + oldMainVnode = mainVnode; + mountedComponent = component; + } + + return v.update(props, ...children); + }; + + let directives: Record = {}; + + v.directive = (name: string, directive: Directive) => { + let fullName = `v-${name}`; + if (reservedWords.indexOf(fullName) === -1) { + reservedWords.push(fullName); + directives[fullName] = directive; + } + }; + + let hideDirective = (test: boolean) => (bool: boolean, vnode: Vnode, oldnode?: Vnode | TextVnode) => { + let value = test ? bool : !bool; + if (value) { + let newdom = document.createTextNode(""); + if (oldnode && oldnode.dom && oldnode.dom.parentNode) { + oldnode instanceof Vnode && callRemove(oldnode); + oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); + } + vnode.name = "#text"; + vnode.children = []; + vnode.props = {}; + vnode.dom = newdom as unknown as DomElement; + return false; + } + }; + + v.directive("if", hideDirective(false)); + v.directive("unless", hideDirective(true)); + v.directive("for", (set: unknown[], vnode: Vnode) => { + vnode.children = set.map(vnode.children[0] as (value: unknown) => Function); + }); + v.directive("show", (bool: boolean, vnode: Vnode) => { + (vnode.dom as { style: { display: string } }).style.display = bool ? "" : "none"; + }); + v.directive("class", (classes: { [x: string]: boolean }, vnode: Vnode) => { + for (let name in classes) { + (vnode.dom as DomElement).classList.toggle(name, classes[name]); + } + }); + v.directive("html", (html: string, vnode: Vnode) => { + vnode.children = [trust(html)]; + }); + + v.newInstance = valyrian; + + return v; +} + +export const v = valyrian(); diff --git a/bench/iterations.test.js b/bench/iterations.test.js deleted file mode 100644 index 0e541d2..0000000 --- a/bench/iterations.test.js +++ /dev/null @@ -1,127 +0,0 @@ -/* eslint-disable eqeqeq */ -let { compare, benchmark, before } = require("buffalo-test"); - -import expect from "expect"; - -compare.skip("Set.has vs [].indexOf", () => { - let set = new Set(); - set.add("hello"); - set.add("world"); - - let arr = ["hello", "world"]; - - before(() => { - expect(set.has("hello")).toEqual(true); - expect(set.has("world")).toEqual(true); - expect(set.has("hola")).toEqual(false); - - expect(arr.indexOf("hello") !== -1).toEqual(true); - expect(arr.indexOf("world") !== -1).toEqual(true); - expect(arr.indexOf("hola") !== -1).toEqual(false); - }); - - benchmark("Set.has", () => { - set.has("hello"); - set.has("world"); - set.has("hola"); - }); - - benchmark("[].indexOf", () => { - arr.indexOf("hello") !== -1; - arr.indexOf("world") !== -1; - arr.indexOf("hola") !== -1; - }); -}); - -compare.skip("Object.keys for loop vs Object.keys for of vs for in", () => { - let obj = { - a: 1, - b: 2, - c: 3, - d: 4, - e: 5, - f: 6, - g: 7 - }; - - benchmark("Object.keys for loop", () => { - let keys = Object.keys(obj); - - for (let i = 0; i--; ) { - keys[i]; - } - }); - - benchmark("Object.keys for of", () => { - let keys = Object.keys(obj); - - for (let key of keys) { - key; - } - }); - - benchmark("for in", () => { - for (let key in obj) { - key; - } - }); -}); - -compare.skip("typeof function vs startsWith vs charAt vs string[0]", () => { - let obj = { - oncreate() {}, - b: null, - c: 1, - d: new Date(), - e: {} - }; - - benchmark("typeof function", () => { - for (let key in obj) { - typeof key === "function"; - } - }); - - benchmark("startsWith", () => { - for (let key in obj) { - // eslint-disable-next-line sonarjs/no-ignored-return - key.startsWith("on"); - } - }); - - benchmark("charAt", () => { - for (let key in obj) { - key.charAt(0) === "o" && key.charAt(1) === "n"; - } - }); - - benchmark("string[0]", () => { - for (let key in obj) { - key[0] === "o" && key[1] === "n"; - } - }); -}); - -compare.skip("Array.isArray vs typeof object & Array.isArray", () => { - let a = []; - let b = {}; - let c = null; - let d = "string"; - let e = 1; - - benchmark("Array.isArray", () => { - Array.isArray(a); - Array.isArray(b); - Array.isArray(c); - Array.isArray(d); - Array.isArray(e); - }); - - benchmark("typeof object & Array.isArray", () => { - typeof a === "object" && Array.isArray(a); - typeof b === "object" && Array.isArray(b); - typeof c === "object" && Array.isArray(c); - typeof d === "object" && Array.isArray(d); - typeof e === "object" && Array.isArray(e); - }); -}); diff --git a/bench/iterations_bench.js b/bench/iterations_bench.js new file mode 100644 index 0000000..67f6f9d --- /dev/null +++ b/bench/iterations_bench.js @@ -0,0 +1,553 @@ +/* eslint-disable eqeqeq */ +let { compare, benchmark, before, beforeEach } = require("buffalo-test"); + +import expect from "expect"; + +compare.skip("Set.has vs [].indexOf", () => { + let set = new Set(); + set.add("hello"); + set.add("world"); + + let arr = ["hello", "world"]; + + before(() => { + expect(set.has("hello")).toEqual(true); + expect(set.has("world")).toEqual(true); + expect(set.has("hola")).toEqual(false); + + expect(arr.indexOf("hello") !== -1).toEqual(true); + expect(arr.indexOf("world") !== -1).toEqual(true); + expect(arr.indexOf("hola") !== -1).toEqual(false); + }); + + benchmark("Set.has", () => { + set.has("hello"); + set.has("world"); + set.has("hola"); + }); + + benchmark("[].indexOf", () => { + arr.indexOf("hello") !== -1; + arr.indexOf("world") !== -1; + arr.indexOf("hola") !== -1; + }); +}); + +compare.skip("Object.keys for loop vs Object.keys for of vs for in", () => { + let obj = { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6, + g: 7 + }; + + benchmark("Object.keys for loop", () => { + let keys = Object.keys(obj); + + for (let i = 0; i--; ) { + keys[i]; + } + }); + + benchmark("Object.keys for of", () => { + let keys = Object.keys(obj); + + for (let key of keys) { + key; + } + }); + + benchmark("for in", () => { + for (let key in obj) { + key; + } + }); +}); + +compare.skip("typeof function vs startsWith vs charAt vs string[0]", () => { + let obj = { + oncreate() {}, + b: null, + c: 1, + d: new Date(), + e: {} + }; + + benchmark("typeof function", () => { + for (let key in obj) { + typeof key === "function"; + } + }); + + benchmark("startsWith", () => { + for (let key in obj) { + // eslint-disable-next-line sonarjs/no-ignored-return + key.startsWith("on"); + } + }); + + benchmark("charAt", () => { + for (let key in obj) { + key.charAt(0) === "o" && key.charAt(1) === "n"; + } + }); + + benchmark("string[0]", () => { + for (let key in obj) { + key[0] === "o" && key[1] === "n"; + } + }); +}); + +compare.skip("Array.isArray vs typeof object & Array.isArray", () => { + let a = []; + let b = {}; + let c = null; + let d = "string"; + let e = 1; + + benchmark("Array.isArray", () => { + Array.isArray(a); + Array.isArray(b); + Array.isArray(c); + Array.isArray(d); + Array.isArray(e); + }); + + benchmark("typeof object & Array.isArray", () => { + typeof a === "object" && Array.isArray(a); + typeof b === "object" && Array.isArray(b); + typeof c === "object" && Array.isArray(c); + typeof d === "object" && Array.isArray(d); + typeof e === "object" && Array.isArray(e); + }); +}); + +compare.skip("string comparison vs instance comparison vs property comparison", () => { + class A { + name = "a"; + } + class B { + b = "b"; + } + let classA = new A(); + let classB = new B(); + + benchmark("string comparison", () => { + classA.name === "a"; + classB.name === "b"; + }); + + benchmark("instance comparison", () => { + classA instanceof A; + classB instanceof B; + }); + + benchmark("property comparison", () => { + "name" in classA; + "name" in classB; + }); + + benchmark("property string comparison", () => { + !classA.name; + !classB.name; + }); + + benchmark("typeof comparison", () => { + typeof classA.name === "string"; + typeof classB.name === "string"; + }); +}); + +compare.skip("Object with property equals true vs set vs map vs string array", () => { + let obj = { + alpha: true, + beta: true, + gamma: true, + delta: true, + epsilon: true, + zeta: true + }; + + let set = new Set(); + let map = new Map(); + let arr = []; + + for (let key in obj) { + set.add(key); + map.set(key, true); + arr.push(key); + } + + beforeEach(() => { + expect(obj.alpha).toEqual(true); + expect(obj.capa).toBeUndefined(); + expect(set.has("alpha")).toEqual(true); + expect(set.has("capa")).toEqual(false); + expect(map.has("alpha")).toEqual(true); + expect(map.has("capa")).toEqual(false); + expect(arr.indexOf("alpha") !== -1).toEqual(true); + expect(arr.indexOf("capa") !== -1).toEqual(false); + }); + + benchmark("Object with property equals true", () => { + obj.alpha === true; + obj.beta === true; + obj.gamma === true; + obj.delta === true; + obj.epsilon === true; + obj.zeta === true; + + obj.capa === true; + obj.capa === true; + obj.capa === true; + obj.capa === true; + obj.capa === true; + obj.capa === true; + }); + + benchmark("key in object", () => { + "alpha" in obj === true; + "beta" in obj === true; + "gamma" in obj === true; + "delta" in obj === true; + "epsilon" in obj === true; + "zeta" in obj === true; + + "capa" in obj === true; + "capa" in obj === true; + "capa" in obj === true; + "capa" in obj === true; + "capa" in obj === true; + "capa" in obj === true; + }); + + benchmark("set", () => { + set.has("alpha") === true; + set.has("beta") === true; + set.has("gamma") === true; + set.has("delta") === true; + set.has("epsilon") === true; + set.has("zeta") === true; + + set.has("capa") === true; + set.has("capa") === true; + set.has("capa") === true; + set.has("capa") === true; + set.has("capa") === true; + set.has("capa") === true; + }); + + benchmark("map", () => { + map.has("alpha") === true; + map.has("beta") === true; + map.has("gamma") === true; + map.has("delta") === true; + map.has("epsilon") === true; + map.has("zeta") === true; + + map.has("capa") === true; + map.has("capa") === true; + map.has("capa") === true; + map.has("capa") === true; + map.has("capa") === true; + map.has("capa") === true; + }); + + benchmark("string array", () => { + arr.indexOf("alpha") !== -1; + arr.indexOf("beta") !== -1; + arr.indexOf("gamma") !== -1; + arr.indexOf("delta") !== -1; + arr.indexOf("epsilon") !== -1; + arr.indexOf("zeta") !== -1; + + arr.indexOf("capa") !== -1; + arr.indexOf("capa") !== -1; + arr.indexOf("capa") !== -1; + arr.indexOf("capa") !== -1; + arr.indexOf("capa") !== -1; + arr.indexOf("capa") !== -1; + }); +}); + +compare.skip("For loop if/continue vs if/else", () => { + let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + beforeEach(() => { + expect(arr.length).toEqual(10); + }); + + benchmark("for loop if/continue", () => { + let sum = 0; + for (let i = 0; i < arr.length; i++) { + if (arr[i] % 2 === 0) { + sum -= arr[i]; + continue; + } + sum += arr[i]; + } + }); + + benchmark("for loop if/else", () => { + let sum = 0; + for (let i = 0; i < arr.length; i++) { + if (arr[i] % 2 === 0) { + sum -= arr[i]; + } else { + sum += arr[i]; + } + } + }); +}); + +compare.skip("map array of strings vs reduce with object keys equals index", () => { + let objects = [{ key: "a" }, { key: "b" }, { key: "c" }, { key: "d" }, { key: "e" }, { key: "f" }, { key: "g" }, { key: "h" }, { key: "i" }, { key: "j" }]; + + beforeEach(() => { + let arrayByMap = objects.map((obj) => obj.key); + expect(arrayByMap[0]).toEqual("a"); + + let objectByReduce = objects.reduce((acc, obj, i) => { + acc[obj.key] = i; + return acc; + }, {}); + expect(objectByReduce.a).toEqual(0); + + let arrayByFor = []; + for (let i = 0; i < objects.length; i++) { + arrayByFor.push(objects[i].key); + } + expect(arrayByFor[0]).toEqual("a"); + + let objectByFor = {}; + for (let i = 0; i < objects.length; i++) { + objectByFor[objects[i].key] = i; + } + expect(objectByFor.a).toEqual(0); + + let objectMapByFor = new Map(); + for (let i = 0; i < objects.length; i++) { + objectMapByFor.set(objects[i].key, i); + } + expect(objectMapByFor.get("a")).toEqual(0); + }); + + benchmark("map array of strings", () => { + let arrayByMap = objects.map((obj) => obj.key); + arrayByMap.indexOf("a") !== -1; + arrayByMap.indexOf("b") !== -1; + arrayByMap.indexOf("c") !== -1; + arrayByMap.indexOf("d") !== -1; + arrayByMap.indexOf("e") !== -1; + arrayByMap.indexOf("f") !== -1; + arrayByMap.indexOf("g") !== -1; + arrayByMap.indexOf("h") !== -1; + arrayByMap.indexOf("i") !== -1; + arrayByMap.indexOf("j") !== -1; + + arrayByMap.indexOf("k") !== -1; + arrayByMap.indexOf("l") !== -1; + arrayByMap.indexOf("m") !== -1; + arrayByMap.indexOf("n") !== -1; + arrayByMap.indexOf("o") !== -1; + arrayByMap.indexOf("p") !== -1; + arrayByMap.indexOf("q") !== -1; + arrayByMap.indexOf("r") !== -1; + arrayByMap.indexOf("s") !== -1; + arrayByMap.indexOf("t") !== -1; + }); + + benchmark("reduce with object keys equals index", () => { + let objectByReduce = objects.reduce((acc, obj, i) => { + acc[obj.key] = i; + return acc; + }, {}); + objectByReduce.a === 0; + objectByReduce.b === 1; + objectByReduce.c === 2; + objectByReduce.d === 3; + objectByReduce.e === 4; + objectByReduce.f === 5; + objectByReduce.g === 6; + objectByReduce.h === 7; + objectByReduce.i === 8; + objectByReduce.j === 9; + + objectByReduce.k === 10; + objectByReduce.l === 11; + objectByReduce.m === 12; + objectByReduce.n === 13; + objectByReduce.o === 14; + objectByReduce.p === 15; + objectByReduce.q === 16; + objectByReduce.r === 17; + objectByReduce.s === 18; + objectByReduce.t === 19; + }); + + benchmark("array by for", () => { + let arrayByFor = []; + for (let i = 0; i < objects.length; i++) { + arrayByFor.push(objects[i].key); + } + arrayByFor.indexOf("a") !== -1; + arrayByFor.indexOf("b") !== -1; + arrayByFor.indexOf("c") !== -1; + arrayByFor.indexOf("d") !== -1; + arrayByFor.indexOf("e") !== -1; + arrayByFor.indexOf("f") !== -1; + arrayByFor.indexOf("g") !== -1; + arrayByFor.indexOf("h") !== -1; + arrayByFor.indexOf("i") !== -1; + arrayByFor.indexOf("j") !== -1; + + arrayByFor.indexOf("k") !== -1; + arrayByFor.indexOf("l") !== -1; + arrayByFor.indexOf("m") !== -1; + arrayByFor.indexOf("n") !== -1; + arrayByFor.indexOf("o") !== -1; + arrayByFor.indexOf("p") !== -1; + arrayByFor.indexOf("q") !== -1; + arrayByFor.indexOf("r") !== -1; + arrayByFor.indexOf("s") !== -1; + arrayByFor.indexOf("t") !== -1; + }); + + benchmark("object by for", () => { + let objectByFor = {}; + for (let i = 0; i < objects.length; i++) { + objectByFor[objects[i].key] = i; + } + objectByFor.a === 0; + objectByFor.b === 1; + objectByFor.c === 2; + objectByFor.d === 3; + objectByFor.e === 4; + objectByFor.f === 5; + objectByFor.g === 6; + objectByFor.h === 7; + objectByFor.i === 8; + objectByFor.j === 9; + + objectByFor.k === 10; + objectByFor.l === 11; + objectByFor.m === 12; + objectByFor.n === 13; + objectByFor.o === 14; + objectByFor.p === 15; + objectByFor.q === 16; + objectByFor.r === 17; + objectByFor.s === 18; + objectByFor.t === 19; + }); + + benchmark("object map by for", () => { + let objectMapByFor = new Map(); + for (let i = 0; i < objects.length; i++) { + objectMapByFor.set(objects[i].key, i); + } + objectMapByFor.get("a") === 0; + objectMapByFor.get("b") === 1; + objectMapByFor.get("c") === 2; + objectMapByFor.get("d") === 3; + objectMapByFor.get("e") === 4; + objectMapByFor.get("f") === 5; + objectMapByFor.get("g") === 6; + objectMapByFor.get("h") === 7; + objectMapByFor.get("i") === 8; + objectMapByFor.get("j") === 9; + + objectMapByFor.get("k") === 10; + objectMapByFor.get("l") === 11; + objectMapByFor.get("m") === 12; + objectMapByFor.get("n") === 13; + objectMapByFor.get("o") === 14; + objectMapByFor.get("p") === 15; + objectMapByFor.get("q") === 16; + objectMapByFor.get("r") === 17; + objectMapByFor.get("s") === 18; + objectMapByFor.get("t") === 19; + }); +}); + +compare.skip("Symbol access vs direct access", () => { + beforeEach(() => { + function Component1() {} + function Component2() {} + + Component1.__valyrian__ = { + render: () => {} + }; + + let ValyrianSymbol = Symbol("Valyrian"); + Component2[ValyrianSymbol] = { + render: () => {} + }; + + expect(Component1.__valyrian__).toBeDefined(); + expect(Component2[ValyrianSymbol]).toBeDefined(); + + Reflect.deleteProperty(Component1, "__valyrian__"); + Reflect.deleteProperty(Component2, ValyrianSymbol); + + expect(Component1.__valyrian__).toBeUndefined(); + expect(Component2[ValyrianSymbol]).toBeUndefined(); + }); + + benchmark("Direct access access", () => { + function Component1() {} + + for (let i = 1000; i--; ) { + Component1.__valyrian__ = { + render: () => {} + }; + } + + for (let i = 1000; i--; ) { + "__valyrian__" in Component1; + } + + for (let i = 1000; i--; ) { + Component1.__valyrian__; + } + + for (let i = 1000; i--; ) { + Component1.__valyrian__.render; + } + + for (let i = 1000; i--; ) { + Reflect.deleteProperty(Component1, "__valyrian__"); + } + }); + + benchmark("Symbol access access", () => { + function Component2() {} + let symbol = Symbol("Valyrian"); + + for (let i = 1000; i--; ) { + Component2[symbol] = { + render: () => {} + }; + } + + for (let i = 1000; i--; ) { + symbol in Component2; + } + + for (let i = 1000; i--; ) { + Component2[symbol]; + } + + for (let i = 1000; i--; ) { + Component2[symbol].render; + } + + for (let i = 1000; i--; ) { + Reflect.deleteProperty(Component2, symbol); + } + }); +}); diff --git a/bench/mount_n_update.test.js b/bench/mount_n_update_bench.js similarity index 60% rename from bench/mount_n_update.test.js rename to bench/mount_n_update_bench.js index d135762..c160db6 100644 --- a/bench/mount_n_update.test.js +++ b/bench/mount_n_update_bench.js @@ -1,86 +1,139 @@ -let { compare, benchmark, before } = require("buffalo-test"); +/* eslint-disable indent */ +let { compare, benchmark, before, afterCycle } = require("buffalo-test"); -import "../lib/index.ts"; +const { mount, update, unmount, v, use } = require("../lib/index"); -import expect from "expect"; -import nodePlugin from "../plugins/node"; -import vOld from "./index-old"; +const expect = require("expect"); +require("../plugins/node"); +const { v: vOld } = require("./index-old.ts"); +const plugin = require("../plugins/hooks"); + +use(plugin); +const useEffect = plugin.useEffect; +const useMemo = plugin.useMemo; + +console.log(vOld); +console.log(v); let VNext = v; let data = { before: [], + before2: [], update1: [], update2: [] }; -function createNode({ className, i }) { - return { - class: className, - data: i, - onbeforeupdate(n, o) { - return n.props.data !== o.props.data || n.props.class !== o.props.class; +function createNode({ className, i }, v) { + return v( + "div", + { + class: className, + data: i, + onbeforeupdate(n, o) { + return n.props.data !== o.props.data || n.props.class !== o.props.class; + }, + id: className + i, + style: "font-size:" + i + "px", + autocomplete: "off", + focus: false, + onclick() { + // console.log("clicked", this); + } }, - id: className + i, - style: "font-size:" + i + "px", - autocomplete: "off", - focus: false, - onclick() { - // console.log("clicked", this); - } - }; + "Hello" + ); } for (let i = 1000; i--; ) { - data.before.push(createNode({ className: "ok", i })); + data.before.push(createNode({ className: "ok", i }, vOld)); + data.before2.push(createNode({ className: "ok", i }, VNext)); if (i % 3) { - data.before.push(createNode({ className: "ok", i: i + 3 })); + data.before.push(createNode({ className: "ok", i: i + 3 }, vOld)); + data.before2.push(createNode({ className: "ok", i: i + 3 }, VNext)); } else { - data.before.push(createNode({ className: "not-ok", i })); + data.before.push(createNode({ className: "not-ok", i }, vOld)); + data.before2.push(createNode({ className: "not-ok", i }, VNext)); } - data.update2.push(createNode({ className: "ok", i: 1000 - i })); + data.update1.push(createNode({ className: "ok", i: 1000 - i }, vOld)); + data.update2.push(createNode({ className: "ok", i: 1000 - i }, VNext)); } compare("Mount and update: Mount multiple types", () => { let date = new Date(); let useData = false; let Component = () => vOld("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? data.before : null); - let Component2 = () => VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? data.before : null); - let Component3 = () => VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? data.before : null); + let Component2 = () => VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? data.before2 : null); before(() => { expect(vOld.mount("body", Component)).toEqual(`
Hello1${date}[object Object]Hello
`); - expect(VNext.mount("body", Component2)).toEqual(`
Hello1${date}[object Object]Hello
`); - expect(VNext.mount("body", Component3)).toEqual(`
Hello1${date}[object Object]Hello
`); + expect(mount("body", Component2)).toEqual(`
Hello1${date}[object Object]Hello
`); + vOld.unMount(); + unmount(Component2); useData = true; }); - benchmark("Valyrian 5.0.8", () => { + afterCycle(() => { vOld.unMount(); + unmount(Component2); + }); + + benchmark("Valyrian 5.0.8", () => { vOld.mount("body", Component); }); benchmark("Valyrian next", () => { - VNext.mount("body", Component2); + mount("body", Component2); }); }); compare("Mount and update: Mount single text", () => { + let Component = () => "hello world"; + let Component2 = () => "hello world"; + + before(() => { + expect(vOld.mount("body", Component)).toEqual(`hello world`); + vOld.unMount(); + expect(mount("body", Component2)).toEqual(`hello world`); + unmount(Component2); + }); + + afterCycle(() => { + vOld.unMount(); + unmount(Component2); + }); + + benchmark("Valyrian 5.0.8", () => { + vOld.mount("body", Component); + }); + + benchmark("Valyrian next", () => { + mount("body", Component2); + }); +}); + +compare("Mount and update: Mount single text in div", () => { let Component = () => vOld("div", null, ["hello world"]); let Component2 = () => VNext("div", null, ["hello world"]); before(() => { expect(vOld.mount("body", Component)).toEqual(`
hello world
`); - expect(VNext.mount("body", Component2)).toEqual(`
hello world
`); + expect(mount("body", Component2)).toEqual(`
hello world
`); + vOld.unMount(); + unmount(Component2); }); - benchmark("Valyrian 5.0.8", () => { + afterCycle(() => { vOld.unMount(); + unmount(Component2); + }); + + benchmark("Valyrian 5.0.8", () => { vOld.mount("body", Component); }); benchmark("Valyrian next", () => { - VNext.mount("body", Component2); + mount("body", Component2); }); }); @@ -91,21 +144,30 @@ compare("Mount and update: Update multiple types", () => { let Component = () => vOld("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? (updateData ? data.update1 : data.before) : null); let Component2 = () => - VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? (updateData ? data.update1 : data.before) : null); + VNext("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]], useData ? (updateData ? data.update2 : data.before2) : null); - before(() => { - expect(vOld.mount("body", Component)).toEqual(`
Hello1${date}[object Object]Hello
`); + before(async () => { + let oldDate = date; + expect(vOld.mount("body", Component)).toEqual(`
Hello1${oldDate}[object Object]Hello
`); + await new Promise((resolve) => setTimeout(resolve, 1000)); + date = new Date(); expect(vOld.update()).toEqual(`
Hello1${date}[object Object]Hello
`); - expect(VNext.mount("body", Component2)).toEqual(`
Hello1${date}[object Object]Hello
`); - expect(VNext.update()).toEqual(`
Hello1${date}[object Object]Hello
`); - vOld.unMount(); + date = oldDate; + let before = mount("body", Component2); + expect(before).toEqual(`
Hello1${oldDate}[object Object]Hello
`); + await new Promise((resolve) => setTimeout(resolve, 1000)); + date = new Date(); + let after = update(Component2); + expect(after).toEqual(`
Hello1${date}[object Object]Hello
`); + useData = true; + vOld.unMount(); + vOld.mount("body", Component); + mount("body", Component2); }); benchmark("Valyrian 5.0.8", () => { - vOld.unMount(); - vOld.mount("body", Component); updateData = true; vOld.update(); updateData = false; @@ -116,13 +178,12 @@ compare("Mount and update: Update multiple types", () => { }); benchmark("Valyrian next", () => { - VNext.mount("body", Component2); updateData = true; - VNext.update(); + update(Component2); updateData = false; - VNext.update(); + update(Component2); updateData = true; - VNext.update(); + update(Component2); updateData = false; }); }); @@ -134,16 +195,17 @@ compare("Mount and update: Update single text", () => { before(() => { expect(vOld.mount("body", Component)).toEqual(`
hello world
`); - expect(VNext.mount("body", Component2)).toEqual(`
hello world
`); + expect(mount("body", Component2)).toEqual(`
hello world
`); updateData = true; expect(vOld.update()).toEqual(`
hello moon
`); - expect(VNext.update()).toEqual(`
hello moon
`); + expect(update(Component2)).toEqual(`
hello moon
`); updateData = false; + vOld.unMount(); + vOld.mount("body", Component); + mount("body", Component2); }); benchmark("Valyrian 5.0.8", () => { - vOld.unMount(); - vOld.mount("body", Component); updateData = true; vOld.update(); updateData = false; @@ -153,13 +215,12 @@ compare("Mount and update: Update single text", () => { }); benchmark("Valyrian next", () => { - VNext.mount("body", Component2); updateData = true; - VNext.update(); + update(Component2); updateData = false; - VNext.update(); + update(Component2); updateData = true; - VNext.update(); + update(Component2); }); }); @@ -207,6 +268,7 @@ compare("Mount and update: Render list", () => { }) ); + vOld.unMount(); let before = vOld.mount("body", component); keys = [...test.set]; let after = vOld.update(); @@ -230,9 +292,9 @@ compare("Mount and update: Render list", () => { }) ); - let before = VNext.mount("body", component); + let before = mount("body", component); keys = [...test.set]; - let after = VNext.update(); + let after = update(component); let afterString = getString(test.set); @@ -275,10 +337,10 @@ compare("Mount and update: Render list", () => { }) ); - VNext.mount("body", component); + mount("body", component); for (let test of tests) { keys = [...test.set]; - VNext.update(); + update(component); } }); }); @@ -351,9 +413,9 @@ compare("Mount and update: Render keyed list", () => { ); console.log(test.name); - let before = VNext.mount("body", component); + let before = mount("body", component); keys = [...test.set]; - let after = VNext.update(); + let after = update(component); let afterString = getString(test.set); @@ -397,9 +459,9 @@ compare("Mount and update: Render keyed list", () => { ); for (let test of tests) { - VNext.mount("body", component); + mount("body", component); keys = [...test.set]; - VNext.update(); + update(component); } }); }); @@ -476,9 +538,9 @@ compare("Mount and update: Render keyed list -> stress", () => { ); console.log(test.name); - let before = VNext.mount("body", component); + let before = mount("body", component); keys = [...test.set]; - let after = VNext.update(); + let after = update(component); let afterString = getString(test.set); @@ -522,9 +584,9 @@ compare("Mount and update: Render keyed list -> stress", () => { ); for (let test of tests) { - VNext.mount("body", component); + mount("body", component); keys = [...test.set]; - VNext.update(); + update(component); } }); }); @@ -581,9 +643,9 @@ compare("Mount and update: Render keyed list -> swap keys on large set", () => { }) ); - let before = VNext.mount("body", component); + let before = mount("body", component); keys = [...updatedLargeSet]; - let after = VNext.update(); + let after = update(component); let afterString = getString(updatedLargeSet); @@ -623,8 +685,189 @@ compare("Mount and update: Render keyed list -> swap keys on large set", () => { }) ); - VNext.mount("body", component); + mount("body", component); keys = [...updatedLargeSet]; - VNext.update(); + update(component); + }); +}); + +compare("Mount and update: Update class", () => { + // Init with 1000 words + let words = [...Array(1000).keys()].map((key) => `word ${key}`); + let useData = false; + let updateClass = ""; + let updateClass2 = ""; + let Component = () => + vOld( + "div", + {}, + useData + ? words.map((word) => + vOld( + "span", + { class: updateClass === word ? "selected" : false, onbeforeupdate: (vnode, oldVnode) => vnode.props.class !== oldVnode.props.class }, + word + ) + ) + : vOld( + "div", + { class: updateClass === "test" ? "test" : false, onbeforeupdate: (vnode, oldVnode) => vnode.props.class !== oldVnode.props.class }, + "test" + ) + ); + let Component2 = () => ( +
+ {useData ? ( + words.map((word) => ( + vnode.props.class !== oldVnode.props.class}> + {word} + + )) + ) : ( +
vnode.props.class !== oldVnode.props.class}> + test +
+ )} +
+ ); + + before(() => { + let before = vOld.mount("body", Component); + expect(before).toEqual("
test
"); + let before2 = mount("body", Component2); + expect(before2).toEqual("
test
"); + + updateClass = "test"; + updateClass2 = "test"; + + let after = vOld.update(); + expect(after).toEqual('
test
'); + let after2 = update(Component2); + expect(after2).toEqual('
test
'); + useData = true; + updateClass = ""; + updateClass2 = ""; + }); + + benchmark("vOld update", () => { + vOld.update(); + updateClass = updateClass === "word 10" ? "word 100" : "word 10"; + }); + + benchmark("VNext update", () => { + update(Component2); + updateClass2 = updateClass2 === "word 10" ? "word 100" : "word 10"; + }); +}); + +compare("Mount and update: Update class with hooks vs shouldupdate property", () => { + // Init with 1000 words + let words = [...Array(1000).keys()].map((key) => `word ${key}`); + let useData = false; + let updateClass = ""; + let updateClass2 = ""; + let Component = () => ( +
+ {useData ? ( + words.map((word) => ( + vnode.props.class !== oldVnode.props.class}> + {word} + + )) + ) : ( +
vnode.props.class !== oldVnode.props.class}> + test +
+ )} +
+ ); + + let Component2 = () => ( +
+ {useData + ? words.map((word) => + useMemo(() => {word}, [updateClass2 === word ? "selected" : false]) + ) + : useMemo(() =>
test
, [updateClass2 === "test" ? "test" : false])} +
+ ); + + before(() => { + let before = mount("body", Component); + expect(before).toEqual("
test
"); + let before2 = mount("body", Component2); + expect(before2).toEqual("
test
"); + + updateClass = "test"; + updateClass2 = "test"; + + let after = update(Component); + expect(after).toEqual('
test
'); + let after2 = update(Component2); + expect(after2).toEqual('
test
'); + useData = true; + updateClass = ""; + updateClass2 = ""; + }); + + benchmark("shouldupdate property", () => { + update(Component); + updateClass = updateClass === "word 10" ? "word 100" : "word 10"; + }); + + benchmark("useMemo hook", () => { + update(Component2); + updateClass2 = updateClass2 === "word 10" ? "word 100" : "word 10"; + }); +}); + +compare("Lifecycle vs hooks", () => { + let lifecycleCount = 0; + let plusLifeCycle = () => (lifecycleCount += 1); + + let hooksCount = 0; + let plusHooks = () => (hooksCount += 1); + + let LifecycleComponent = () => { + return ( +
+ Hello world +
+ ); + }; + + let HooksComponent = () => { + // useEffect(plusHooks, []); // Only create replaced by the next line + useEffect(plusHooks); // Create & Update + useEffect(plusHooks, null); // Remove + return
Hello world
; + }; + + before(() => { + mount("body", LifecycleComponent); + expect(lifecycleCount).toEqual(1); + update(LifecycleComponent); + expect(lifecycleCount).toEqual(2); + unmount(LifecycleComponent); + expect(lifecycleCount).toEqual(3); + + mount("body", HooksComponent); + expect(hooksCount).toEqual(1); + update(HooksComponent); + expect(hooksCount).toEqual(2); + unmount(HooksComponent); + expect(hooksCount).toEqual(3); + }); + + benchmark(`Hooks`, () => { + mount("body", HooksComponent); + update(HooksComponent); + unmount(HooksComponent); + }); + + benchmark(`Lifecycle`, () => { + mount("body", LifecycleComponent); + update(LifecycleComponent); + unmount(LifecycleComponent); }); }); diff --git a/dist/@types/lib/index.d.ts b/dist/@types/lib/index.d.ts index a0f4dbe..86ba9a2 100644 --- a/dist/@types/lib/index.d.ts +++ b/dist/@types/lib/index.d.ts @@ -1,106 +1,4 @@ -declare type VnodeOrUnknown = VnodeComponent | Vnode | TextVnode | any; -declare type DomAttribute = { - nodeName: string; - nodeValue: string; -}; -declare type DomElement = (HTMLElement | SVGElement) & Record; -declare type Props = { - key?: string | number; - data?: string; - oncreate?: { - (vnode: Vnode): never; - }; - onupdate?: { - (vnode: Vnode, oldVnode: Vnode | TextVnode): never; - }; - onremove?: { - (oldVnode: Vnode): never; - }; - onbeforeupdate?: { - (vnode: Vnode, oldVnode: Vnode | TextVnode): undefined | boolean; - }; -} & Record; -declare type Component = (props?: Record | null, children?: VnodeOrUnknown) => VnodeOrUnknown | VnodeOrUnknown[]; -declare type ValyrianComponent = Component | (Record & { - view: Component; -}); -declare type Current = { - parentVnode?: Vnode; - oldParentVnode?: Vnode; - component?: VnodeComponent; -}; -interface Plugin { - (v: Valyrian, options?: Record): never; -} -interface Directive { - (value: any, vnode: Vnode, oldVnode?: Vnode | TextVnode): void | boolean; -} -interface ValyrianEventHandler { - (a: Event, dom: DomElement): void; -} -interface Vnode { - name: string; - props: Props; - children: VnodeOrUnknown[]; - dom?: DomElement; - onCleanup?: FunctionConstructor[]; - isSVG?: boolean; - processed?: boolean; -} -declare class Vnode implements Vnode { - name: string; - props: Props; - children: VnodeOrUnknown[]; - dom?: DomElement; - onCleanup?: FunctionConstructor[]; - isSVG?: boolean; - processed?: boolean; - constructor(name: string, props: Props, children: VnodeOrUnknown); -} -interface TextVnode { - dom?: Text; - nodeValue: string; -} -declare class TextVnode implements TextVnode { - dom?: Text; - nodeValue: string; - constructor(nodeValue: string); -} -interface VnodeComponent { - component: ValyrianComponent; - props: Props; - children: VnodeOrUnknown[]; -} -declare class VnodeComponent implements VnodeComponent { - component: ValyrianComponent; - props: Props; - children: VnodeOrUnknown[]; - constructor(component: ValyrianComponent, props: Props, children: VnodeOrUnknown[]); -} -interface Valyrian { - (tagOrComponent: string | ValyrianComponent, props?: Props | null, children?: VnodeOrUnknown): Vnode | VnodeComponent; - fragment: (props: Props, children: VnodeOrUnknown[]) => VnodeOrUnknown[]; - isMounted: boolean; - isNode: boolean; - reservedWords: string[]; - current: Current; - trust: (htmlString: string) => Vnode[]; - usePlugin: (plugin: Plugin, options: Record) => void; - onCleanup: (callback: typeof Function) => void; - updateProperty: (name: string, newVnode: Vnode & { - dom: DomElement; - }, oldNode: Vnode & { - dom: DomElement; - }) => void; - update: (props?: Props | null, ...children: VnodeOrUnknown) => string | void; - mount: (container: string | DomElement, component: ValyrianComponent, props?: Props | null, ...children: VnodeOrUnknown[]) => string | void; - unMount: () => string | boolean | void; - directive: (directive: string, handler: Directive) => void; - newInstance: () => Valyrian; - [x: string]: any; -} -declare let isNode: boolean; -declare function createElement(tagName: string, isSVG?: boolean): DomElement; -declare function domToVnode(dom: DomElement): Vnode; -declare const trust: (htmlString: string) => Vnode[]; -declare function valyrian(): Valyrian; +/*** Vnode ***/ +import { Valyrian } from "./interfaces"; +/*** Hyperscript ***/ +export declare const v: Valyrian; diff --git a/dist/@types/lib/interfaces.d.ts b/dist/@types/lib/interfaces.d.ts new file mode 100644 index 0000000..f502b5e --- /dev/null +++ b/dist/@types/lib/interfaces.d.ts @@ -0,0 +1,117 @@ +/*** Interfaces ***/ +export interface DomElement extends Element { + [key: string]: any; +} +export interface Props { + key?: string | number; + data?: string; + oncreate?: { + (vnode: IVnode): never; + }; + onupdate?: { + (vnode: IVnode, oldVnode: IVnode): never; + }; + onremove?: { + (oldVnode: IVnode): never; + }; + shouldupdate?: { + (vnode: IVnode, oldVnode: IVnode): undefined | boolean; + }; + [key: string | number | symbol]: any; +} +export interface Children extends Array { +} +export interface IVnode { + new (tag: string, props: Props, children: Children): IVnode; + tag: string; + props: Props; + children: Children; + dom?: DomElement; + isSVG?: boolean; + processed?: boolean; + component?: Component | POJOComponent; + nodeValue?: string; + [key: string | number | symbol]: any; +} +export interface Component { + (props?: Record | null, children?: Children): IVnode | Children; + [key: string | number | symbol]: any; +} +export interface POJOComponent { + view: Component; + [key: string | number | symbol]: any; +} +export declare type ValyrianComponent = Component | POJOComponent; +export interface VnodeComponent extends IVnode { + tag: "__component__"; + component: ValyrianComponent; +} +export interface VnodeWithDom extends IVnode { + dom: DomElement; +} +export interface Directive { + (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void; +} +export interface ValyrianApp { + isMounted: boolean; + eventListenerNames: Record; + onCleanup: Function[]; + onUnmount: Function[]; + onMount: Function[]; + onUpdate: Function[]; + eventListener?: EventListener; + mainVnode?: VnodeWithDom; + container?: DomElement; + [key: string | number | symbol]: any; +} +export interface MountedValyrianApp extends ValyrianApp { + eventListener: EventListener; + mainVnode: VnodeWithDom; + container: DomElement; +} +export interface Current { + app?: ValyrianApp; + component?: ValyrianComponent; + vnode?: VnodeWithDom; + oldVnode?: VnodeWithDom; +} +export interface Directives { + [key: string]: Directive; +} +export interface ReservedProps { + [key: string]: true; +} +export interface Plugin { + (valyrian: Valyrian, options?: Record): void | any; +} +export interface Valyrian { + (tagOrComponent: string | ValyrianComponent, props: Props, ...children: Children): IVnode | VnodeComponent; + fragment: (props: Props, ...children: Children) => Children; + current: Current; + directives: Directives; + reservedProps: ReservedProps; + isVnode: (object?: unknown | IVnode) => object is IVnode; + isComponent: (component?: unknown | ValyrianComponent) => component is ValyrianComponent; + isVnodeComponent: (vnode?: unknown | VnodeComponent) => vnode is VnodeComponent; + isNodeJs: boolean; + trust: (htmlString: string) => Children; + onCleanup: (fn: Function) => void; + onUnmount: (fn: Function) => void; + onMount: (fn: Function) => void; + onUpdate: (fn: Function) => void; + mount: (container: DomElement | string, component: ValyrianComponent | IVnode) => void | string; + update: (component: ValyrianComponent | IVnode) => void | string; + unmount: (component: ValyrianComponent | IVnode) => void | string; + setAttribute: (name: string, value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void; + directive: (name: string, directive: Directive) => void; + use: (plugin: Plugin, options?: Record) => void | any; + [key: string | number | symbol]: any; +} +declare global { + namespace JSX { + type Element = IVnode; + interface IntrinsicElements { + [elemName: string]: any; + } + } +} diff --git a/dist/@types/plugins/hooks.d.ts b/dist/@types/plugins/hooks.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/hooks.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/node.d.ts b/dist/@types/plugins/node.d.ts deleted file mode 100644 index 81979ce..0000000 --- a/dist/@types/plugins/node.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { inline }; - export { sw }; - export { icons }; - export const htmlToDom: (html: any, options?: {}) => any; - export const domToHtml: (dom: any) => any; - export const domToHyperscript: (childNodes: any, depth?: number) => any; - export const htmlToHyperscript: (html: any) => string; - export function hyperscriptToHtml(...args: any[]): any; - export { plugin as default }; -} -declare function inline(...args: any[]): Promise; -declare namespace inline { - function extensions(...extensions: any[]): void; - function css(file: any, options?: {}): any[] | Promise; - function js(file: any, options?: {}): any[] | Promise; - function uncss(renderedHtml: any, options?: {}): string | Promise; -} -declare function sw(file: any, options?: {}): Promise; -declare function icons(source: any, configuration?: {}): Promise; -declare namespace icons { - namespace options { - export const iconsPath: null; - export const linksViewPath: null; - export const path: string; - export const appName: null; - export const appDescription: null; - export const developerName: null; - export const developerURL: null; - export const dir: string; - export const lang: string; - export const background: string; - export const theme_color: string; - export const display: string; - export const orientation: string; - export const start_url: string; - export const version: string; - export const logging: boolean; - export namespace icons_1 { - const android: boolean; - const appleIcon: boolean; - const appleStartup: boolean; - const coast: boolean; - const favicons: boolean; - const firefox: boolean; - const windows: boolean; - const yandex: boolean; - } - export { icons_1 as icons }; - } -} diff --git a/dist/@types/plugins/node.sw.tpl.d.ts b/dist/@types/plugins/node.sw.tpl.d.ts deleted file mode 100644 index 922731c..0000000 --- a/dist/@types/plugins/node.sw.tpl.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare function fetchRequest(event: any): Promise; -declare let Log: { - (...data: any[]): void; - (message?: any, ...optionalParams: any[]): void; -}; -declare namespace config { - const version: string; - const name: string; - const urls: string[]; -} -declare let cacheName: string; diff --git a/dist/@types/plugins/request.d.ts b/dist/@types/plugins/request.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/request.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/router.d.ts b/dist/@types/plugins/router.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/router.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/signals.d.ts b/dist/@types/plugins/signals.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/signals.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/store.d.ts b/dist/@types/plugins/store.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/store.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/sw.d.ts b/dist/@types/plugins/sw.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/sw.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/plugins/utils/tree-adapter.d.ts b/dist/@types/plugins/utils/tree-adapter.d.ts deleted file mode 100644 index 810a447..0000000 --- a/dist/@types/plugins/utils/tree-adapter.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { TreeAdapter as default }; diff --git a/dist/@types/plugins/v-model.d.ts b/dist/@types/plugins/v-model.d.ts deleted file mode 100644 index c7e6301..0000000 --- a/dist/@types/plugins/v-model.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export = plugin; -declare function plugin(v: any): void; -declare namespace plugin { - export { plugin as default }; -} diff --git a/dist/@types/register.d.ts b/dist/@types/register.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/@types/register.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/index.cjs b/dist/index.cjs new file mode 100644 index 0000000..0cf5367 --- /dev/null +++ b/dist/index.cjs @@ -0,0 +1,584 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, copyDefault, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key of __getOwnPropNames(module2)) + if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default")) + __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); + } + return target; +}; +var __toCommonJS = /* @__PURE__ */ ((cache) => { + return (module2, temp) => { + return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp); + }; +})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0); + +// lib/index.ts +var lib_exports = {}; +__export(lib_exports, { + v: () => v +}); +var ComponentString = "__component__"; +var TextString = "#text"; +var isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); +var ValyrianSymbol = Symbol("Valyrian"); +var Und = void 0; +var Vnode = function Vnode2(tag, props, children) { + this.props = props; + this.children = children; + this.tag = tag; +}; +function isVnode(object) { + return object instanceof Vnode; +} +function isComponent(component) { + return typeof component === "function" || typeof component === "object" && component !== null && "view" in component; +} +function isVnodeComponent(vnode) { + return vnode instanceof Vnode && vnode.tag === ComponentString; +} +function createDomElement(tag, isSVG = false) { + return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); +} +function domToVnode(dom) { + let vnode = v(dom.tagName.toLowerCase(), {}, ...Array.from(dom.childNodes).filter((child) => child.nodeType === 1 || child.nodeType === 3).map((child) => { + if (child.nodeType === 1) { + return domToVnode(child); + } + let text = new Vnode(TextString, {}, []); + text.nodeValue = String(child.nodeValue); + text.dom = child; + return text; + })); + [].forEach.call(dom.attributes, (prop) => vnode.props[prop.nodeName] = prop.nodeValue); + vnode.dom = dom; + return vnode; +} +var trust = (htmlString) => { + let div = createDomElement("div"); + div.innerHTML = htmlString.trim(); + return [].map.call(div.childNodes, (item) => domToVnode(item)); +}; +var reservedProps = { + key: true, + state: true, + oncreate: true, + onupdate: true, + onremove: true, + shouldupdate: true, + "v-once": true, + "v-if": true, + "v-unless": true, + "v-for": true, + "v-show": true, + "v-class": true, + "v-html": true +}; +var current = {}; +function onCleanup(callback) { + if (current.app?.onCleanup.indexOf(callback) === -1) { + current.app?.onCleanup.push(callback); + } +} +function onUnmount(callback) { + if (current.app?.onUnmount.indexOf(callback) === -1) { + current.app?.onUnmount.push(callback); + } +} +function onMount(callback) { + if (current.app?.onMount.indexOf(callback) === -1) { + current.app?.onMount.push(callback); + } +} +function onUpdate(callback) { + if (current.app?.onUpdate.indexOf(callback) === -1) { + current.app?.onUpdate.push(callback); + } +} +function mount(container, component) { + let appContainer = null; + if (isNodeJs) { + appContainer = typeof container === "string" ? createDomElement(container === "svg" ? "svg" : "div", container === "svg") : container; + } else { + appContainer = typeof container === "string" ? document.querySelectorAll(container)[0] : container; + } + if (!appContainer) { + throw new Error("Container not found"); + } + let vnodeComponent; + if (isVnodeComponent(component)) { + vnodeComponent = component; + } else if (isComponent(component)) { + vnodeComponent = v(component, {}); + } else { + throw new Error("Component must be a Valyrian Component or a Vnode component"); + } + if (component[ValyrianSymbol]) { + unmount(component); + } else { + let eventListener = function(e) { + let dom = e.target; + let name = `v-on${e.type}`; + while (dom) { + if (dom[name]) { + dom[name](e, dom); + if (!e.defaultPrevented) { + update(component); + } + return; + } + dom = dom.parentNode; + } + }; + component[ValyrianSymbol] = { + isMounted: false, + eventListenerNames: {}, + onCleanup: [], + onMount: [], + onUpdate: [], + onUnmount: [] + }; + component[ValyrianSymbol].eventListener = eventListener; + } + component[ValyrianSymbol].component = vnodeComponent; + component[ValyrianSymbol].container = appContainer; + component[ValyrianSymbol].mainVnode = domToVnode(appContainer); + return update(component); +} +function callCleanup(valyrianApp) { + for (let i = 0; i < valyrianApp.onCleanup.length; i++) { + valyrianApp.onCleanup[i](); + } + valyrianApp.onCleanup = []; +} +function callUnmount(valyrianApp) { + for (let i = 0; i < valyrianApp.onUnmount.length; i++) { + valyrianApp.onUnmount[i](); + } + valyrianApp.onUnmount = []; +} +function callMount(valyrianApp) { + for (let i = 0; i < valyrianApp.onMount.length; i++) { + valyrianApp.onMount[i](); + } + valyrianApp.onMount = []; +} +function callUpdate(valyrianApp) { + for (let i = 0; i < valyrianApp.onUpdate.length; i++) { + valyrianApp.onUpdate[i](); + } + valyrianApp.onUpdate = []; +} +function update(component) { + if (component && component[ValyrianSymbol]) { + let valyrianApp = component[ValyrianSymbol]; + current.app = valyrianApp; + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + let oldVnode = valyrianApp.mainVnode; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, [valyrianApp.component]); + valyrianApp.mainVnode.dom = oldVnode.dom; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; + if (valyrianApp.isMounted === false) { + valyrianApp.onMount.length && callMount(valyrianApp); + valyrianApp.isMounted = true; + } else { + valyrianApp.onUpdate.length && callUpdate(valyrianApp); + } + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; + } + } +} +function unmount(component) { + if (!component || !component[ValyrianSymbol]) { + return; + } + let valyrianApp = component[ValyrianSymbol]; + if (valyrianApp.isMounted) { + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + valyrianApp.onUnmount.length && callUnmount(valyrianApp); + let oldVnode = valyrianApp.mainVnode; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, []); + valyrianApp.mainVnode.dom = oldVnode.dom; + valyrianApp.mainVnode.isSVG = oldVnode.isSVG; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; + } + valyrianApp = null; + Reflect.deleteProperty(component, ValyrianSymbol); + } +} +var emptyVnode = new Vnode("__empty__", {}, []); +function onremove(vnode) { + for (let i = 0; i < vnode.children.length; i++) { + vnode.children[i].tag !== TextString && onremove(vnode.children[i]); + } + vnode.props.onremove && vnode.props.onremove(vnode); +} +function sharedSetAttribute(prop, value, vnode, oldVnode) { + if (reservedProps[prop]) { + if (directives[prop]) { + return directives[prop](vnode.props[prop], vnode, oldVnode); + } + return; + } + if (typeof value === "function") { + let valyrianApp = current.app; + if (prop in valyrianApp.eventListenerNames === false) { + valyrianApp.eventListenerNames[prop] = true; + valyrianApp.container.addEventListener(prop.slice(2), valyrianApp.eventListener); + } + vnode.dom[`v-${prop}`] = value; + return; + } + if (prop in vnode.dom && vnode.isSVG === false) { + if (vnode.dom[prop] != value) { + vnode.dom[prop] = value; + } + return; + } + if (!oldVnode || oldVnode.props[prop] !== value) { + if (value === false) { + vnode.dom.removeAttribute(prop); + } else { + vnode.dom.setAttribute(prop, value); + } + } +} +function setAttribute(name, value, vnode, oldVnode) { + vnode.props[name] = value; + sharedSetAttribute(name, value, vnode, oldVnode); +} +function setAttributes(vnode, oldVnode) { + for (let prop in vnode.props) { + if (sharedSetAttribute(prop, vnode.props[prop], vnode, oldVnode) === false) { + return; + } + } + if (oldVnode) { + for (let prop in oldVnode.props) { + if (prop in vnode.props === false && typeof oldVnode.props[prop] !== "function" && prop in reservedProps === false) { + if (prop in oldVnode.dom && vnode.isSVG === false) { + oldVnode.dom[prop] = null; + } else { + oldVnode.dom.removeAttribute(prop); + } + } + } + } +} +function patch(newVnode, oldVnode = emptyVnode, valyrianApp) { + current.vnode = newVnode; + current.oldVnode = oldVnode === emptyVnode ? Und : oldVnode; + let newTree = newVnode.children; + let oldTree = oldVnode.children; + for (let i = 0; i < newTree.length; i++) { + let childVnode = newTree[i]; + if (childVnode instanceof Vnode) { + if (childVnode.tag !== TextString) { + if (childVnode.tag === ComponentString) { + let component = childVnode.component; + current.component = component; + let result = ("view" in component ? component.view : component).call(component, childVnode.props, ...childVnode.children); + newTree.splice(i--, 1, result); + continue; + } + childVnode.isSVG = newVnode.isSVG || childVnode.tag === "svg"; + } + } else if (Array.isArray(childVnode)) { + newTree.splice(i--, 1, ...childVnode); + } else if (childVnode === null || childVnode === Und) { + newTree.splice(i--, 1); + } else { + newTree[i] = new Vnode(TextString, {}, []); + newTree[i].nodeValue = childVnode; + } + } + let oldTreeLength = oldTree.length; + let newTreeLength = newTree.length; + if (newTreeLength === 0) { + for (let i = 0; i < oldTreeLength; i++) { + oldTree[i].tag !== TextString && onremove(oldTree[i]); + } + newVnode.dom.textContent = ""; + return; + } + if (oldTreeLength && "key" in newTree[0].props && "key" in oldTree[0].props) { + let oldKeyedList = {}; + for (let i = 0; i < oldTreeLength; i++) { + oldKeyedList[oldTree[i].props.key] = i; + } + let newKeyedList = {}; + for (let i = 0; i < newTreeLength; i++) { + newKeyedList[newTree[i].props.key] = i; + } + for (let i = 0; i < newTreeLength; i++) { + let childVnode = newTree[i]; + let oldChildVnode = oldTree[oldKeyedList[childVnode.props.key]]; + let shouldPatch = true; + if (oldChildVnode) { + childVnode.dom = oldChildVnode.dom; + if ("v-once" in childVnode.props || childVnode.props.shouldupdate && childVnode.props.shouldupdate(childVnode, oldChildVnode) === false) { + childVnode.children = oldChildVnode.children; + shouldPatch = false; + } else { + setAttributes(childVnode, oldChildVnode); + if (valyrianApp.isMounted) { + childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); + } else { + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + } + } else { + childVnode.dom = createDomElement(childVnode.tag, childVnode.isSVG); + setAttributes(childVnode); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + if (newVnode.dom.childNodes[i] === Und) { + newVnode.dom.appendChild(childVnode.dom); + } else if (newVnode.dom.childNodes[i] !== childVnode.dom) { + oldTree[i] && newKeyedList[oldTree[i].props.key] === Und && onremove(oldTree[i]); + newVnode.dom.replaceChild(childVnode.dom, newVnode.dom.childNodes[i]); + } + shouldPatch && patch(childVnode, oldChildVnode, valyrianApp); + } + for (let i = newTreeLength; i < oldTreeLength; i++) { + if (newKeyedList[oldTree[i].props.key] === Und) { + let oldChildVnode = oldTree[i]; + onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } + } + return; + } + for (let i = 0; i < newTreeLength; i++) { + let newChildVnode = newTree[i]; + if (i < oldTreeLength) { + let oldChildVnode = oldTree[i]; + if (newChildVnode.tag === TextString) { + if (oldChildVnode.tag === TextString) { + newChildVnode.dom = oldChildVnode.dom; + if (newChildVnode.dom.nodeValue != newChildVnode.nodeValue) { + newChildVnode.dom.nodeValue = newChildVnode.nodeValue; + } + continue; + } + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue); + onremove(oldChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); + continue; + } + if (oldChildVnode.tag === newChildVnode.tag) { + newChildVnode.dom = oldChildVnode.dom; + if (newChildVnode.props["v-once"] || newChildVnode.props.shouldupdate && newChildVnode.props.shouldupdate(newChildVnode, oldChildVnode) === false) { + newChildVnode.children = oldChildVnode.children; + continue; + } + setAttributes(newChildVnode, oldChildVnode); + if (valyrianApp.isMounted) { + newChildVnode.props.onupdate && newChildVnode.props.onupdate(newChildVnode, oldChildVnode); + } else { + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + } + patch(newChildVnode, oldChildVnode, valyrianApp); + continue; + } + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); + patch(newChildVnode, emptyVnode, valyrianApp); + continue; + } + if (newChildVnode.tag === TextString) { + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue); + newVnode.dom.appendChild(newChildVnode.dom); + continue; + } + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + newVnode.dom.appendChild(newChildVnode.dom); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + patch(newChildVnode, emptyVnode, valyrianApp); + } + for (let i = newTreeLength; i < oldTreeLength; i++) { + let oldChildVnode = oldTree[i]; + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } +} +function directive(name, directive2) { + let fullName = `v-${name}`; + directives[fullName] = directive2; + reservedProps[fullName] = true; +} +function hideDirective(test) { + return (bool, vnode, oldVnode) => { + let value = test ? bool : !bool; + if (value) { + let newdom = document.createTextNode(""); + if (oldVnode && oldVnode.dom && oldVnode.dom.parentNode) { + oldVnode.tag !== TextString && onremove(oldVnode); + oldVnode.dom.parentNode.replaceChild(newdom, oldVnode.dom); + } + vnode.tag = TextString; + vnode.children = []; + vnode.props = {}; + vnode.dom = newdom; + return false; + } + }; +} +var directives = { + "v-if": hideDirective(false), + "v-unless": hideDirective(true), + "v-for": (set, vnode) => { + vnode.children = set.map(vnode.children[0]); + }, + "v-show": (bool, vnode) => { + vnode.dom.style.display = bool ? "" : "none"; + }, + "v-class": (classes, vnode) => { + for (let name in classes) { + vnode.dom.classList.toggle(name, classes[name]); + } + }, + "v-html": (html, vnode) => { + vnode.children = [trust(html)]; + }, + "v-model": ([model, property, event], vnode, oldVnode) => { + let value; + let handler; + if (vnode.name === "input") { + event = event || "oninput"; + switch (vnode.props.type) { + case "checkbox": { + if (Array.isArray(model[property])) { + handler = (e) => { + let val = e.target.value; + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + }; + value = model[property].indexOf(vnode.dom.value) !== -1; + } else if ("value" in vnode.props) { + handler = () => { + if (model[property] === vnode.props.value) { + model[property] = null; + } else { + model[property] = vnode.props.value; + } + }; + value = model[property] === vnode.props.value; + } else { + handler = () => model[property] = !model[property]; + value = model[property]; + } + setAttribute("checked", value, vnode, oldVnode); + break; + } + case "radio": { + setAttribute("checked", model[property] === vnode.dom.value, vnode, oldVnode); + break; + } + default: { + setAttribute("value", model[property], vnode, oldVnode); + } + } + } else if (vnode.name === "select") { + event = event || "onclick"; + if (vnode.props.multiple) { + handler = (e) => { + let val = e.target.value; + if (e.ctrlKey) { + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + } else { + model[property].splice(0, model[property].length); + model[property].push(val); + } + }; + vnode.children.forEach((child) => { + if (child.tag === "option") { + let value2 = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = model[property].indexOf(value2) !== -1; + } + }); + } else { + vnode.children.forEach((child) => { + if (child.tag === "option") { + let value2 = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = value2 === model[property]; + } + }); + } + } else if (vnode.name === "textarea") { + event = event || "oninput"; + vnode.children = [model[property]]; + } + if (!vnode.props[event]) { + if (!handler) { + handler = (e) => model[property] = e.target.value; + } + setAttribute(event, handler, vnode, oldVnode); + } + } +}; +var plugins = /* @__PURE__ */ new Map(); +function use(plugin, options) { + if (plugins.has(plugin)) { + return plugins.get(plugin); + } + let result = plugin(v, options); + plugins.set(plugin, result); + return result; +} +var v = function v2(tagOrComponent, props, ...children) { + if (typeof tagOrComponent === "string") { + return new Vnode(tagOrComponent, props || {}, children); + } + const vnode = new Vnode("__component__", props || {}, children); + vnode.component = tagOrComponent; + return vnode; +}; +v.fragment = (props, ...children) => { + return children; +}; +v.current = current; +v.directives = directives; +v.reservedProps = reservedProps; +v.isVnode = isVnode; +v.isComponent = isComponent; +v.isVnodeComponent = isVnodeComponent; +v.isNodeJs = isNodeJs; +v.trust = trust; +v.onCleanup = onCleanup; +v.onUnmount = onUnmount; +v.onMount = onMount; +v.onUpdate = onUpdate; +v.mount = mount; +v.unmount = unmount; +v.update = update; +v.setAttribute = setAttribute; +v.directive = directive; +v.use = use; +module.exports = __toCommonJS(lib_exports); diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..c436b4b --- /dev/null +++ b/dist/index.js @@ -0,0 +1,559 @@ +// lib/index.ts +var ComponentString = "__component__"; +var TextString = "#text"; +var isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); +var ValyrianSymbol = Symbol("Valyrian"); +var Und = void 0; +var Vnode = function Vnode2(tag, props, children) { + this.props = props; + this.children = children; + this.tag = tag; +}; +function isVnode(object) { + return object instanceof Vnode; +} +function isComponent(component) { + return typeof component === "function" || typeof component === "object" && component !== null && "view" in component; +} +function isVnodeComponent(vnode) { + return vnode instanceof Vnode && vnode.tag === ComponentString; +} +function createDomElement(tag, isSVG = false) { + return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); +} +function domToVnode(dom) { + let vnode = v(dom.tagName.toLowerCase(), {}, ...Array.from(dom.childNodes).filter((child) => child.nodeType === 1 || child.nodeType === 3).map((child) => { + if (child.nodeType === 1) { + return domToVnode(child); + } + let text = new Vnode(TextString, {}, []); + text.nodeValue = String(child.nodeValue); + text.dom = child; + return text; + })); + [].forEach.call(dom.attributes, (prop) => vnode.props[prop.nodeName] = prop.nodeValue); + vnode.dom = dom; + return vnode; +} +var trust = (htmlString) => { + let div = createDomElement("div"); + div.innerHTML = htmlString.trim(); + return [].map.call(div.childNodes, (item) => domToVnode(item)); +}; +var reservedProps = { + key: true, + state: true, + oncreate: true, + onupdate: true, + onremove: true, + shouldupdate: true, + "v-once": true, + "v-if": true, + "v-unless": true, + "v-for": true, + "v-show": true, + "v-class": true, + "v-html": true +}; +var current = {}; +function onCleanup(callback) { + if (current.app?.onCleanup.indexOf(callback) === -1) { + current.app?.onCleanup.push(callback); + } +} +function onUnmount(callback) { + if (current.app?.onUnmount.indexOf(callback) === -1) { + current.app?.onUnmount.push(callback); + } +} +function onMount(callback) { + if (current.app?.onMount.indexOf(callback) === -1) { + current.app?.onMount.push(callback); + } +} +function onUpdate(callback) { + if (current.app?.onUpdate.indexOf(callback) === -1) { + current.app?.onUpdate.push(callback); + } +} +function mount(container, component) { + let appContainer = null; + if (isNodeJs) { + appContainer = typeof container === "string" ? createDomElement(container === "svg" ? "svg" : "div", container === "svg") : container; + } else { + appContainer = typeof container === "string" ? document.querySelectorAll(container)[0] : container; + } + if (!appContainer) { + throw new Error("Container not found"); + } + let vnodeComponent; + if (isVnodeComponent(component)) { + vnodeComponent = component; + } else if (isComponent(component)) { + vnodeComponent = v(component, {}); + } else { + throw new Error("Component must be a Valyrian Component or a Vnode component"); + } + if (component[ValyrianSymbol]) { + unmount(component); + } else { + let eventListener = function(e) { + let dom = e.target; + let name = `v-on${e.type}`; + while (dom) { + if (dom[name]) { + dom[name](e, dom); + if (!e.defaultPrevented) { + update(component); + } + return; + } + dom = dom.parentNode; + } + }; + component[ValyrianSymbol] = { + isMounted: false, + eventListenerNames: {}, + onCleanup: [], + onMount: [], + onUpdate: [], + onUnmount: [] + }; + component[ValyrianSymbol].eventListener = eventListener; + } + component[ValyrianSymbol].component = vnodeComponent; + component[ValyrianSymbol].container = appContainer; + component[ValyrianSymbol].mainVnode = domToVnode(appContainer); + return update(component); +} +function callCleanup(valyrianApp) { + for (let i = 0; i < valyrianApp.onCleanup.length; i++) { + valyrianApp.onCleanup[i](); + } + valyrianApp.onCleanup = []; +} +function callUnmount(valyrianApp) { + for (let i = 0; i < valyrianApp.onUnmount.length; i++) { + valyrianApp.onUnmount[i](); + } + valyrianApp.onUnmount = []; +} +function callMount(valyrianApp) { + for (let i = 0; i < valyrianApp.onMount.length; i++) { + valyrianApp.onMount[i](); + } + valyrianApp.onMount = []; +} +function callUpdate(valyrianApp) { + for (let i = 0; i < valyrianApp.onUpdate.length; i++) { + valyrianApp.onUpdate[i](); + } + valyrianApp.onUpdate = []; +} +function update(component) { + if (component && component[ValyrianSymbol]) { + let valyrianApp = component[ValyrianSymbol]; + current.app = valyrianApp; + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + let oldVnode = valyrianApp.mainVnode; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, [valyrianApp.component]); + valyrianApp.mainVnode.dom = oldVnode.dom; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; + if (valyrianApp.isMounted === false) { + valyrianApp.onMount.length && callMount(valyrianApp); + valyrianApp.isMounted = true; + } else { + valyrianApp.onUpdate.length && callUpdate(valyrianApp); + } + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; + } + } +} +function unmount(component) { + if (!component || !component[ValyrianSymbol]) { + return; + } + let valyrianApp = component[ValyrianSymbol]; + if (valyrianApp.isMounted) { + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + valyrianApp.onUnmount.length && callUnmount(valyrianApp); + let oldVnode = valyrianApp.mainVnode; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, []); + valyrianApp.mainVnode.dom = oldVnode.dom; + valyrianApp.mainVnode.isSVG = oldVnode.isSVG; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; + } + valyrianApp = null; + Reflect.deleteProperty(component, ValyrianSymbol); + } +} +var emptyVnode = new Vnode("__empty__", {}, []); +function onremove(vnode) { + for (let i = 0; i < vnode.children.length; i++) { + vnode.children[i].tag !== TextString && onremove(vnode.children[i]); + } + vnode.props.onremove && vnode.props.onremove(vnode); +} +function sharedSetAttribute(prop, value, vnode, oldVnode) { + if (reservedProps[prop]) { + if (directives[prop]) { + return directives[prop](vnode.props[prop], vnode, oldVnode); + } + return; + } + if (typeof value === "function") { + let valyrianApp = current.app; + if (prop in valyrianApp.eventListenerNames === false) { + valyrianApp.eventListenerNames[prop] = true; + valyrianApp.container.addEventListener(prop.slice(2), valyrianApp.eventListener); + } + vnode.dom[`v-${prop}`] = value; + return; + } + if (prop in vnode.dom && vnode.isSVG === false) { + if (vnode.dom[prop] != value) { + vnode.dom[prop] = value; + } + return; + } + if (!oldVnode || oldVnode.props[prop] !== value) { + if (value === false) { + vnode.dom.removeAttribute(prop); + } else { + vnode.dom.setAttribute(prop, value); + } + } +} +function setAttribute(name, value, vnode, oldVnode) { + vnode.props[name] = value; + sharedSetAttribute(name, value, vnode, oldVnode); +} +function setAttributes(vnode, oldVnode) { + for (let prop in vnode.props) { + if (sharedSetAttribute(prop, vnode.props[prop], vnode, oldVnode) === false) { + return; + } + } + if (oldVnode) { + for (let prop in oldVnode.props) { + if (prop in vnode.props === false && typeof oldVnode.props[prop] !== "function" && prop in reservedProps === false) { + if (prop in oldVnode.dom && vnode.isSVG === false) { + oldVnode.dom[prop] = null; + } else { + oldVnode.dom.removeAttribute(prop); + } + } + } + } +} +function patch(newVnode, oldVnode = emptyVnode, valyrianApp) { + current.vnode = newVnode; + current.oldVnode = oldVnode === emptyVnode ? Und : oldVnode; + let newTree = newVnode.children; + let oldTree = oldVnode.children; + for (let i = 0; i < newTree.length; i++) { + let childVnode = newTree[i]; + if (childVnode instanceof Vnode) { + if (childVnode.tag !== TextString) { + if (childVnode.tag === ComponentString) { + let component = childVnode.component; + current.component = component; + let result = ("view" in component ? component.view : component).call(component, childVnode.props, ...childVnode.children); + newTree.splice(i--, 1, result); + continue; + } + childVnode.isSVG = newVnode.isSVG || childVnode.tag === "svg"; + } + } else if (Array.isArray(childVnode)) { + newTree.splice(i--, 1, ...childVnode); + } else if (childVnode === null || childVnode === Und) { + newTree.splice(i--, 1); + } else { + newTree[i] = new Vnode(TextString, {}, []); + newTree[i].nodeValue = childVnode; + } + } + let oldTreeLength = oldTree.length; + let newTreeLength = newTree.length; + if (newTreeLength === 0) { + for (let i = 0; i < oldTreeLength; i++) { + oldTree[i].tag !== TextString && onremove(oldTree[i]); + } + newVnode.dom.textContent = ""; + return; + } + if (oldTreeLength && "key" in newTree[0].props && "key" in oldTree[0].props) { + let oldKeyedList = {}; + for (let i = 0; i < oldTreeLength; i++) { + oldKeyedList[oldTree[i].props.key] = i; + } + let newKeyedList = {}; + for (let i = 0; i < newTreeLength; i++) { + newKeyedList[newTree[i].props.key] = i; + } + for (let i = 0; i < newTreeLength; i++) { + let childVnode = newTree[i]; + let oldChildVnode = oldTree[oldKeyedList[childVnode.props.key]]; + let shouldPatch = true; + if (oldChildVnode) { + childVnode.dom = oldChildVnode.dom; + if ("v-once" in childVnode.props || childVnode.props.shouldupdate && childVnode.props.shouldupdate(childVnode, oldChildVnode) === false) { + childVnode.children = oldChildVnode.children; + shouldPatch = false; + } else { + setAttributes(childVnode, oldChildVnode); + if (valyrianApp.isMounted) { + childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); + } else { + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + } + } else { + childVnode.dom = createDomElement(childVnode.tag, childVnode.isSVG); + setAttributes(childVnode); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } + if (newVnode.dom.childNodes[i] === Und) { + newVnode.dom.appendChild(childVnode.dom); + } else if (newVnode.dom.childNodes[i] !== childVnode.dom) { + oldTree[i] && newKeyedList[oldTree[i].props.key] === Und && onremove(oldTree[i]); + newVnode.dom.replaceChild(childVnode.dom, newVnode.dom.childNodes[i]); + } + shouldPatch && patch(childVnode, oldChildVnode, valyrianApp); + } + for (let i = newTreeLength; i < oldTreeLength; i++) { + if (newKeyedList[oldTree[i].props.key] === Und) { + let oldChildVnode = oldTree[i]; + onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } + } + return; + } + for (let i = 0; i < newTreeLength; i++) { + let newChildVnode = newTree[i]; + if (i < oldTreeLength) { + let oldChildVnode = oldTree[i]; + if (newChildVnode.tag === TextString) { + if (oldChildVnode.tag === TextString) { + newChildVnode.dom = oldChildVnode.dom; + if (newChildVnode.dom.nodeValue != newChildVnode.nodeValue) { + newChildVnode.dom.nodeValue = newChildVnode.nodeValue; + } + continue; + } + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue); + onremove(oldChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); + continue; + } + if (oldChildVnode.tag === newChildVnode.tag) { + newChildVnode.dom = oldChildVnode.dom; + if (newChildVnode.props["v-once"] || newChildVnode.props.shouldupdate && newChildVnode.props.shouldupdate(newChildVnode, oldChildVnode) === false) { + newChildVnode.children = oldChildVnode.children; + continue; + } + setAttributes(newChildVnode, oldChildVnode); + if (valyrianApp.isMounted) { + newChildVnode.props.onupdate && newChildVnode.props.onupdate(newChildVnode, oldChildVnode); + } else { + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + } + patch(newChildVnode, oldChildVnode, valyrianApp); + continue; + } + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); + patch(newChildVnode, emptyVnode, valyrianApp); + continue; + } + if (newChildVnode.tag === TextString) { + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue); + newVnode.dom.appendChild(newChildVnode.dom); + continue; + } + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + newVnode.dom.appendChild(newChildVnode.dom); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + patch(newChildVnode, emptyVnode, valyrianApp); + } + for (let i = newTreeLength; i < oldTreeLength; i++) { + let oldChildVnode = oldTree[i]; + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } +} +function directive(name, directive2) { + let fullName = `v-${name}`; + directives[fullName] = directive2; + reservedProps[fullName] = true; +} +function hideDirective(test) { + return (bool, vnode, oldVnode) => { + let value = test ? bool : !bool; + if (value) { + let newdom = document.createTextNode(""); + if (oldVnode && oldVnode.dom && oldVnode.dom.parentNode) { + oldVnode.tag !== TextString && onremove(oldVnode); + oldVnode.dom.parentNode.replaceChild(newdom, oldVnode.dom); + } + vnode.tag = TextString; + vnode.children = []; + vnode.props = {}; + vnode.dom = newdom; + return false; + } + }; +} +var directives = { + "v-if": hideDirective(false), + "v-unless": hideDirective(true), + "v-for": (set, vnode) => { + vnode.children = set.map(vnode.children[0]); + }, + "v-show": (bool, vnode) => { + vnode.dom.style.display = bool ? "" : "none"; + }, + "v-class": (classes, vnode) => { + for (let name in classes) { + vnode.dom.classList.toggle(name, classes[name]); + } + }, + "v-html": (html, vnode) => { + vnode.children = [trust(html)]; + }, + "v-model": ([model, property, event], vnode, oldVnode) => { + let value; + let handler; + if (vnode.name === "input") { + event = event || "oninput"; + switch (vnode.props.type) { + case "checkbox": { + if (Array.isArray(model[property])) { + handler = (e) => { + let val = e.target.value; + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + }; + value = model[property].indexOf(vnode.dom.value) !== -1; + } else if ("value" in vnode.props) { + handler = () => { + if (model[property] === vnode.props.value) { + model[property] = null; + } else { + model[property] = vnode.props.value; + } + }; + value = model[property] === vnode.props.value; + } else { + handler = () => model[property] = !model[property]; + value = model[property]; + } + setAttribute("checked", value, vnode, oldVnode); + break; + } + case "radio": { + setAttribute("checked", model[property] === vnode.dom.value, vnode, oldVnode); + break; + } + default: { + setAttribute("value", model[property], vnode, oldVnode); + } + } + } else if (vnode.name === "select") { + event = event || "onclick"; + if (vnode.props.multiple) { + handler = (e) => { + let val = e.target.value; + if (e.ctrlKey) { + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + } else { + model[property].splice(0, model[property].length); + model[property].push(val); + } + }; + vnode.children.forEach((child) => { + if (child.tag === "option") { + let value2 = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = model[property].indexOf(value2) !== -1; + } + }); + } else { + vnode.children.forEach((child) => { + if (child.tag === "option") { + let value2 = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = value2 === model[property]; + } + }); + } + } else if (vnode.name === "textarea") { + event = event || "oninput"; + vnode.children = [model[property]]; + } + if (!vnode.props[event]) { + if (!handler) { + handler = (e) => model[property] = e.target.value; + } + setAttribute(event, handler, vnode, oldVnode); + } + } +}; +var plugins = /* @__PURE__ */ new Map(); +function use(plugin, options) { + if (plugins.has(plugin)) { + return plugins.get(plugin); + } + let result = plugin(v, options); + plugins.set(plugin, result); + return result; +} +var v = function v2(tagOrComponent, props, ...children) { + if (typeof tagOrComponent === "string") { + return new Vnode(tagOrComponent, props || {}, children); + } + const vnode = new Vnode("__component__", props || {}, children); + vnode.component = tagOrComponent; + return vnode; +}; +v.fragment = (props, ...children) => { + return children; +}; +v.current = current; +v.directives = directives; +v.reservedProps = reservedProps; +v.isVnode = isVnode; +v.isComponent = isComponent; +v.isVnodeComponent = isVnodeComponent; +v.isNodeJs = isNodeJs; +v.trust = trust; +v.onCleanup = onCleanup; +v.onUnmount = onUnmount; +v.onMount = onMount; +v.onUpdate = onUpdate; +v.mount = mount; +v.unmount = unmount; +v.update = update; +v.setAttribute = setAttribute; +v.directive = directive; +v.use = use; +export { + v +}; diff --git a/dist/index.min.js b/dist/index.min.js new file mode 100644 index 0000000..0a6c24b --- /dev/null +++ b/dist/index.min.js @@ -0,0 +1 @@ +(()=>{var e="__component__",n="#text",o=Boolean("undefined"!=typeof process&&process.versions&&process.versions.node),t=Symbol("Valyrian"),r=void 0,i=function(e,n,o){this.props=n,this.children=o,this.tag=e};function p(e){return"function"==typeof e||"object"==typeof e&&null!==e&&"view"in e}function d(n){return n instanceof i&&n.tag===e}function l(e,n=!1){return n?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}function a(e){let o=U(e.tagName.toLowerCase(),{},...Array.from(e.childNodes).filter(e=>1===e.nodeType||3===e.nodeType).map(e=>{if(1===e.nodeType)return a(e);let o=new i(n,{},[]);return o.nodeValue=String(e.nodeValue),o.dom=e,o}));return[].forEach.call(e.attributes,e=>o.props[e.nodeName]=e.nodeValue),o.dom=e,o}var s=e=>{let n=l("div");return n.innerHTML=e.trim(),[].map.call(n.childNodes,e=>a(e))},u={key:!0,state:!0,oncreate:!0,onupdate:!0,onremove:!0,shouldupdate:!0,"v-once":!0,"v-if":!0,"v-unless":!0,"v-for":!0,"v-show":!0,"v-class":!0,"v-html":!0},c={};function m(e){for(let n=0;n{if(e?o:!o){let e=document.createTextNode("");return r&&r.dom&&r.dom.parentNode&&(r.tag!==n&&g(r),r.dom.parentNode.replaceChild(e,r.dom)),t.tag=n,t.children=[],t.props={},t.dom=e,!1}}}var M={"v-if":N(!1),"v-unless":N(!0),"v-for":(e,n)=>{n.children=e.map(n.children[0])},"v-show":(e,n)=>{n.dom.style.display=e?"":"none"},"v-class":(e,n)=>{for(let o in e)n.dom.classList.toggle(o,e[o])},"v-html":(e,n)=>{n.children=[s(e)]},"v-model":([e,n,o],t,r)=>{let i,p;if("input"===t.name)switch(o=o||"oninput",t.props.type){case"checkbox":Array.isArray(e[n])?(p=o=>{let t=o.target.value,r=e[n].indexOf(t);-1===r?e[n].push(t):e[n].splice(r,1)},i=-1!==e[n].indexOf(t.dom.value)):"value"in t.props?(p=()=>{e[n]===t.props.value?e[n]=null:e[n]=t.props.value},i=e[n]===t.props.value):(p=()=>e[n]=!e[n],i=e[n]),y("checked",i,t,r);break;case"radio":y("checked",e[n]===t.dom.value,t,r);break;default:y("value",e[n],t,r)}else"select"===t.name?(o=o||"onclick",t.props.multiple?(p=o=>{let t=o.target.value;if(o.ctrlKey){let o=e[n].indexOf(t);-1===o?e[n].push(t):e[n].splice(o,1)}else e[n].splice(0,e[n].length),e[n].push(t)},t.children.forEach(o=>{if("option"===o.tag){let t="value"in o.props?o.props.value:o.children.join("").trim();o.props.selected=-1!==e[n].indexOf(t)}})):t.children.forEach(o=>{if("option"===o.tag){let t="value"in o.props?o.props.value:o.children.join("").trim();o.props.selected=t===e[n]}})):"textarea"===t.name&&(o=o||"oninput",t.children=[e[n]]);t.props[o]||(p||(p=o=>e[n]=o.target.value),y(o,p,t,r))}},x=new Map;var U=function(e,n,...o){if("string"==typeof e)return new i(e,n||{},o);const t=new i("__component__",n||{},o);return t.component=e,t};U.fragment=(e,...n)=>n,U.current=c,U.directives=M,U.reservedProps=u,U.isVnode=function(e){return e instanceof i},U.isComponent=p,U.isVnodeComponent=d,U.isNodeJs=o,U.trust=s,U.onCleanup=function(e){-1===c.app?.onCleanup.indexOf(e)&&c.app?.onCleanup.push(e)},U.onUnmount=function(e){-1===c.app?.onUnmount.indexOf(e)&&c.app?.onUnmount.push(e)},U.onMount=function(e){-1===c.app?.onMount.indexOf(e)&&c.app?.onMount.push(e)},U.onUpdate=function(e){-1===c.app?.onUpdate.indexOf(e)&&c.app?.onUpdate.push(e)},U.mount=function(e,n){let r,i=null;if(i=o?"string"==typeof e?l("svg"===e?"svg":"div","svg"===e):e:"string"==typeof e?document.querySelectorAll(e)[0]:e,!i)throw new Error("Container not found");if(d(n))r=n;else{if(!p(n))throw new Error("Component must be a Valyrian Component or a Vnode component");r=U(n,{})}if(n[t])h(n);else{let e=function(e){let o=e.target,t=`v-on${e.type}`;for(;o;){if(o[t])return o[t](e,o),void(e.defaultPrevented||f(n));o=o.parentNode}};n[t]={isMounted:!1,eventListenerNames:{},onCleanup:[],onMount:[],onUpdate:[],onUnmount:[]},n[t].eventListener=e}return n[t].component=r,n[t].container=i,n[t].mainVnode=a(i),f(n)},U.unmount=h,U.update=f,U.setAttribute=y,U.directive=function(e,n){let o=`v-${e}`;M[o]=n,u[o]=!0},U.use=function(e,n){if(x.has(e))return x.get(e);let o=e(U,n);return x.set(e,o),o};var k={v:U};"undefined"!=typeof module?module.exports=k:self.Valyrian=k})(); \ No newline at end of file diff --git a/dist/index.min.js.map b/dist/index.min.js.map new file mode 100644 index 0000000..683f413 --- /dev/null +++ b/dist/index.min.js.map @@ -0,0 +1 @@ +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2xpYi9pbmRleC50cyJdLCJuYW1lcyI6WyJDb21wb25lbnRTdHJpbmciLCJUZXh0U3RyaW5nIiwiaXNOb2RlSnMiLCJCb29sZWFuIiwicHJvY2VzcyIsInZlcnNpb25zIiwibm9kZSIsIlZhbHlyaWFuU3ltYm9sIiwiU3ltYm9sIiwiVW5kIiwiVm5vZGUiLCJ0YWciLCJwcm9wcyIsImNoaWxkcmVuIiwidGhpcyIsImlzQ29tcG9uZW50IiwiY29tcG9uZW50IiwiaXNWbm9kZUNvbXBvbmVudCIsInZub2RlIiwiY3JlYXRlRG9tRWxlbWVudCIsImlzU1ZHIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50TlMiLCJjcmVhdGVFbGVtZW50IiwiZG9tVG9Wbm9kZSIsImRvbSIsInYiLCJ0YWdOYW1lIiwidG9Mb3dlckNhc2UiLCJBcnJheSIsImZyb20iLCJjaGlsZE5vZGVzIiwiZmlsdGVyIiwiY2hpbGQiLCJub2RlVHlwZSIsIm1hcCIsInRleHQiLCJub2RlVmFsdWUiLCJTdHJpbmciLCJmb3JFYWNoIiwiY2FsbCIsImF0dHJpYnV0ZXMiLCJwcm9wIiwibm9kZU5hbWUiLCJ0cnVzdCIsImh0bWxTdHJpbmciLCJkaXYiLCJpbm5lckhUTUwiLCJ0cmltIiwiaXRlbSIsInJlc2VydmVkUHJvcHMiLCJrZXkiLCJzdGF0ZSIsIm9uY3JlYXRlIiwib251cGRhdGUiLCJvbnJlbW92ZSIsInNob3VsZHVwZGF0ZSIsImN1cnJlbnQiLCJjYWxsQ2xlYW51cCIsInZhbHlyaWFuQXBwIiwiaSIsIm9uQ2xlYW51cCIsImxlbmd0aCIsInVwZGF0ZSIsImFwcCIsIm9sZFZub2RlIiwibWFpblZub2RlIiwicGF0Y2giLCJpc01vdW50ZWQiLCJvbk1vdW50IiwiY2FsbE1vdW50Iiwib25VcGRhdGUiLCJjYWxsVXBkYXRlIiwidW5tb3VudCIsIm9uVW5tb3VudCIsImNhbGxVbm1vdW50IiwiUmVmbGVjdCIsImRlbGV0ZVByb3BlcnR5IiwiZW1wdHlWbm9kZSIsInNoYXJlZFNldEF0dHJpYnV0ZSIsInZhbHVlIiwiZGlyZWN0aXZlcyIsImV2ZW50TGlzdGVuZXJOYW1lcyIsImNvbnRhaW5lciIsImFkZEV2ZW50TGlzdGVuZXIiLCJzbGljZSIsImV2ZW50TGlzdGVuZXIiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzZXRBdHRyaWJ1dGUiLCJuYW1lIiwic2V0QXR0cmlidXRlcyIsIm5ld1Zub2RlIiwibmV3VHJlZSIsIm9sZFRyZWUiLCJjaGlsZFZub2RlIiwicmVzdWx0IiwidmlldyIsInNwbGljZSIsImlzQXJyYXkiLCJvbGRUcmVlTGVuZ3RoIiwibmV3VHJlZUxlbmd0aCIsIm9sZEtleWVkTGlzdCIsIm5ld0tleWVkTGlzdCIsIm9sZENoaWxkVm5vZGUiLCJzaG91bGRQYXRjaCIsImFwcGVuZENoaWxkIiwicmVwbGFjZUNoaWxkIiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwibmV3Q2hpbGRWbm9kZSIsImNyZWF0ZVRleHROb2RlIiwidGV4dENvbnRlbnQiLCJoaWRlRGlyZWN0aXZlIiwidGVzdCIsImJvb2wiLCJuZXdkb20iLCJzZXQiLCJzdHlsZSIsImRpc3BsYXkiLCJjbGFzc2VzIiwiY2xhc3NMaXN0IiwidG9nZ2xlIiwiaHRtbCIsIm1vZGVsIiwicHJvcGVydHkiLCJldmVudCIsImhhbmRsZXIiLCJ0eXBlIiwiZSIsInZhbCIsInRhcmdldCIsImlkeCIsImluZGV4T2YiLCJwdXNoIiwibXVsdGlwbGUiLCJjdHJsS2V5IiwidmFsdWUyIiwiam9pbiIsInNlbGVjdGVkIiwicGx1Z2lucyIsIk1hcCIsInRhZ09yQ29tcG9uZW50IiwiZnJhZ21lbnQiLCJpc1Zub2RlIiwib2JqZWN0IiwiY2FsbGJhY2siLCJtb3VudCIsInZub2RlQ29tcG9uZW50IiwiYXBwQ29udGFpbmVyIiwicXVlcnlTZWxlY3RvckFsbCIsIkVycm9yIiwiZGVmYXVsdFByZXZlbnRlZCIsImRpcmVjdGl2ZSIsImRpcmVjdGl2ZTIiLCJmdWxsTmFtZSIsInVzZSIsInBsdWdpbiIsIm9wdGlvbnMiLCJoYXMiLCJn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Q3JCLElBQUl2RyxFQUFNdUcsRUFBRUUsT0FDUnpDLEVBQU8sT0FBT3VDLEVBQUVELE9BQ3BCLEtBQU90RyxHQUFLLENBQ1YsR0FBSUEsRUFBSWdFLEdBS04sT0FKQWhFLEVBQUlnRSxHQUFNdUMsRUFBR3ZHLFFBQ1J1RyxFQUFFdUIsa0JBQ0x4RixFQUFPL0MsSUFJWFMsRUFBTUEsRUFBSWtGLGFBbkJkM0YsRUFBVVQsR0FBa0IsQ0FDMUI2RCxXQUFXLEVBQ1hjLG1CQUFvQixHQUNwQnJCLFVBQVcsR0FDWFEsUUFBUyxHQUNURSxTQUFVLEdBQ1ZHLFVBQVcsSUFnQmIxRCxFQUFVVCxHQUFnQitFLGNBQWdCQSxFQVE1QyxPQUxBdEUsRUFBVVQsR0FBZ0JTLFVBQVltSSxFQUN0Q25JLEVBQVVULEdBQWdCNEUsVUFBWWlFLEVBQ3RDcEksRUFBVVQsR0FBZ0IyRCxVQUFZMUMsRUFBVzRILEdBRzFDckYsRUFBTy9DLElBMGdCaEJVLEVBQUUrQyxRQUFVQSxFQUNaL0MsRUFBRXFDLE9BQVNBLEVBRVhyQyxFQUFFOEQsYUFBZUEsRUFDakI5RCxFQUFFOEgsVUF0TEYsU0FBbUIvRCxFQUFjZ0UsR0FDL0IsSUFBSUMsRUFBVyxLQUFLakUsSUFDcEJSLEVBQVd5RSxHQUFZRCxFQUN2QnZHLEVBQWN3RyxJQUFZLEdBb0w1QmhJLEVBQUVpSSxJQXBERixTQUFhQyxFQUFnQkMsR0FDM0IsR0FBSWxCLEVBQVFtQixJQUFJRixHQUNkLE9BQU9qQixFQUFRb0IsSUFBSUgsR0FHckIsSUFBSTdELEVBQVM2RCxFQUFPbEksRUFBR21JLEdBRXZCLE9BREFsQixFQUFRdkIsSUFBSXdDLEVBQVE3RCxHQUNiQSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVzZS1iZWZvcmUtZGVmaW5lICovXG4vKiBlc2xpbnQtZGlzYWJsZSBzb25hcmpzL2NvZ25pdGl2ZS1jb21wbGV4aXR5ICovXG4vKioqIFZub2RlICoqKi9cblxuaW1wb3J0IHtcbiAgQ2hpbGRyZW4sXG4gIEN1cnJlbnQsXG4gIERpcmVjdGl2ZSxcbiAgRGlyZWN0aXZlcyxcbiAgRG9tRWxlbWVudCxcbiAgSVZub2RlLFxuICBNb3VudGVkVmFseXJpYW5BcHAsXG4gIFBsdWdpbixcbiAgUHJvcHMsXG4gIFJlc2VydmVkUHJvcHMsXG4gIFZhbHlyaWFuLFxuICBWYWx5cmlhbkFwcCxcbiAgVmFseXJpYW5Db21wb25lbnQsXG4gIFZub2RlQ29tcG9uZW50LFxuICBWbm9kZVdpdGhEb21cbn0gZnJvbSBcIi4vaW50ZXJmYWNlc1wiO1xuXG4vKioqIENvbnN0YW50cyAqKiovXG5jb25zdCBDb21wb25lbnRTdHJpbmcgPSBcIl9fY29tcG9uZW50X19cIjtcbmNvbnN0IFRleHRTdHJpbmcgPSBcIiN0ZXh0XCI7XG5jb25zdCBpc05vZGVKcyA9IEJvb2xlYW4odHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2Vzcy52ZXJzaW9ucyAmJiBwcm9jZXNzLnZlcnNpb25zLm5vZGUpO1xuY29uc3QgVmFseXJpYW5TeW1ib2wgPSBTeW1ib2woXCJWYWx5cmlhblwiKTtcbmNvbnN0IFVuZCA9IHVuZGVmaW5lZDtcblxuLyoqKiBWbm9kZSAqKiovXG5cbmNvbnN0IFZub2RlID0gZnVuY3Rpb24gVm5vZGUodGhpczogSVZub2RlLCB0YWc6IHN0cmluZywgcHJvcHM6IFByb3BzLCBjaGlsZHJlbjogQ2hpbGRyZW4pIHtcbiAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIHRoaXMudGFnID0gdGFnO1xufSBhcyB1bmtub3duIGFzIElWbm9kZTtcblxuZnVuY3Rpb24gaXNWbm9kZShvYmplY3Q/OiB1bmtub3duIHwgSVZub2RlKTogb2JqZWN0IGlzIElWbm9kZSB7XG4gIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBWbm9kZTtcbn1cblxuZnVuY3Rpb24gaXNDb21wb25lbnQoY29tcG9uZW50PzogdW5rbm93biB8IFZhbHlyaWFuQ29tcG9uZW50KTogY29tcG9uZW50IGlzIFZhbHlyaWFuQ29tcG9uZW50IHtcbiAgcmV0dXJuIHR5cGVvZiBjb21wb25lbnQgPT09IFwiZnVuY3Rpb25cIiB8fCAodHlwZW9mIGNvbXBvbmVudCA9PT0gXCJvYmplY3RcIiAmJiBjb21wb25lbnQgIT09IG51bGwgJiYgXCJ2aWV3XCIgaW4gY29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gaXNWbm9kZUNvbXBvbmVudCh2bm9kZT86IHVua25vd24gfCBWbm9kZUNvbXBvbmVudCk6IHZub2RlIGlzIFZub2RlQ29tcG9uZW50IHtcbiAgcmV0dXJuIHZub2RlIGluc3RhbmNlb2YgVm5vZGUgJiYgdm5vZGUudGFnID09PSBDb21wb25lbnRTdHJpbmc7XG59XG5cbi8qKiogVXRpbCAqKiovXG5cbmZ1bmN0aW9uIGNyZWF0ZURvbUVsZW1lbnQodGFnOiBzdHJpbmcsIGlzU1ZHOiBib29sZWFuID0gZmFsc2UpIHtcbiAgcmV0dXJuIGlzU1ZHID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgdGFnKSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnKTtcbn1cblxuZnVuY3Rpb24gZG9tVG9Wbm9kZShkb206IERvbUVsZW1lbnQpOiBWbm9kZVdpdGhEb20ge1xuICBsZXQgdm5vZGUgPSB2KFxuICAgIGRvbS50YWdOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAge30sXG4gICAgLi4uQXJyYXkuZnJvbShkb20uY2hpbGROb2RlcylcbiAgICAgIC5maWx0ZXIoKGNoaWxkKSA9PiAoY2hpbGQgYXMgRG9tRWxlbWVudCkubm9kZVR5cGUgPT09IDEgfHwgKGNoaWxkIGFzIERvbUVsZW1lbnQpLm5vZGVUeXBlID09PSAzKVxuICAgICAgLm1hcCgoY2hpbGQpID0+IHtcbiAgICAgICAgaWYgKChjaGlsZCBhcyBEb21FbGVtZW50KS5ub2RlVHlwZSA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiBkb21Ub1Zub2RlKGNoaWxkIGFzIERvbUVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRleHQgPSBuZXcgVm5vZGUoVGV4dFN0cmluZywge30sIFtdKTtcbiAgICAgICAgdGV4dC5ub2RlVmFsdWUgPSBTdHJpbmcoKGNoaWxkIGFzIERvbUVsZW1lbnQpLm5vZGVWYWx1ZSk7XG4gICAgICAgIHRleHQuZG9tID0gY2hpbGQgYXMgRG9tRWxlbWVudDtcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgICB9KVxuICApO1xuICBbXS5mb3JFYWNoLmNhbGwoZG9tLmF0dHJpYnV0ZXMsIChwcm9wOiBBdHRyKSA9PiAodm5vZGUucHJvcHNbcHJvcC5ub2RlTmFtZV0gPSBwcm9wLm5vZGVWYWx1ZSkpO1xuICB2bm9kZS5kb20gPSBkb207XG4gIHJldHVybiB2bm9kZSBhcyBWbm9kZVdpdGhEb207XG59XG5cbmNvbnN0IHRydXN0ID0gKGh0bWxTdHJpbmc6IHN0cmluZyk6IENoaWxkcmVuID0+IHtcbiAgbGV0IGRpdiA9IGNyZWF0ZURvbUVsZW1lbnQoXCJkaXZcIik7XG4gIGRpdi5pbm5lckhUTUwgPSBodG1sU3RyaW5nLnRyaW0oKTtcblxuICByZXR1cm4gW10ubWFwLmNhbGwoZGl2LmNoaWxkTm9kZXMsIChpdGVtKSA9PiBkb21Ub1Zub2RlKGl0ZW0pKSBhcyBDaGlsZHJlbjtcbn07XG5cbmNvbnN0IHJlc2VydmVkUHJvcHM6IFJlc2VydmVkUHJvcHMgPSB7XG4gIGtleTogdHJ1ZSxcbiAgc3RhdGU6IHRydWUsXG4gIG9uY3JlYXRlOiB0cnVlLFxuICBvbnVwZGF0ZTogdHJ1ZSxcbiAgb25yZW1vdmU6IHRydWUsXG4gIHNob3VsZHVwZGF0ZTogdHJ1ZSxcbiAgXCJ2LW9uY2VcIjogdHJ1ZSxcblxuICAvLyBCdWlsdCBpbiBkaXJlY3RpdmVzXG4gIFwidi1pZlwiOiB0cnVlLFxuICBcInYtdW5sZXNzXCI6IHRydWUsXG4gIFwidi1mb3JcIjogdHJ1ZSxcbiAgXCJ2LXNob3dcIjogdHJ1ZSxcbiAgXCJ2LWNsYXNzXCI6IHRydWUsXG4gIFwidi1odG1sXCI6IHRydWVcbn07XG5cbi8qKiogTW91bnQgKioqL1xuXG5jb25zdCBjdXJyZW50OiBDdXJyZW50ID0ge307XG5cbmZ1bmN0aW9uIG9uQ2xlYW51cChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKGN1cnJlbnQuYXBwPy5vbkNsZWFudXAuaW5kZXhPZihjYWxsYmFjaykgPT09IC0xKSB7XG4gICAgY3VycmVudC5hcHA/Lm9uQ2xlYW51cC5wdXNoKGNhbGxiYWNrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBvblVubW91bnQoY2FsbGJhY2s6IEZ1bmN0aW9uKSB7XG4gIGlmIChjdXJyZW50LmFwcD8ub25Vbm1vdW50LmluZGV4T2YoY2FsbGJhY2spID09PSAtMSkge1xuICAgIGN1cnJlbnQuYXBwPy5vblVubW91bnQucHVzaChjYWxsYmFjayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gb25Nb3VudChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKGN1cnJlbnQuYXBwPy5vbk1vdW50LmluZGV4T2YoY2FsbGJhY2spID09PSAtMSkge1xuICAgIGN1cnJlbnQuYXBwPy5vbk1vdW50LnB1c2goY2FsbGJhY2spO1xuICB9XG59XG5cbmZ1bmN0aW9uIG9uVXBkYXRlKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICBpZiAoY3VycmVudC5hcHA/Lm9uVXBkYXRlLmluZGV4T2YoY2FsbGJhY2spID09PSAtMSkge1xuICAgIGN1cnJlbnQuYXBwPy5vblVwZGF0ZS5wdXNoKGNhbGxiYWNrKTtcbiAgfVxufVxuXG4vKlxuICAqIE1vdW50cyBhIGNvbXBvbmVudCB0byB0aGUgRE9NXG4gIG1vdW50KCcjYXBwJywgKCkgPT4gPGRpdj5IZWxsbyB3b3JsZDwvZGl2Pik7IC8vIEFwcCBpcyBhIEZ1bmN0aW9uYWwgQ29tcG9uZW50XG4gIG1vdW50KCcjYXBwJywgeyB2aWV3OiAoKSA9PiA8ZGl2PkhlbGxvIHdvcmxkPC9kaXY+IH0pOyAvLyBBcHAgaXMgYSBQT0pPIGNvbXBvbmVudCB3aXRoIGEgdmlldyBtZXRob2RcbiAgbW91bnQoJyNhcHAnLCBjbGFzc0luc3RhbmNlKTsgLy8gQXBwIGlzIGEgY2xhc3MgaW5zdGFuY2Ugd2l0aCBhIHZpZXcgbWV0aG9kXG4gIG1vdW50KCcjYXBwJywgPEFwcD48ZGl2PkhlbGxvIHdvcmxkPC9kaXY+PC9BcHA+KTsgLy8gQXBwIGlzIGEgVm5vZGUgY29tcG9uZW50IChWbm9kZSB3aXRoIHRhZyBfX2NvbXBvbmVudF9fKVxuKi9cblxuZnVuY3Rpb24gbW91bnQoY29udGFpbmVyOiBEb21FbGVtZW50IHwgc3RyaW5nLCBjb21wb25lbnQ6IFZhbHlyaWFuQ29tcG9uZW50IHwgSVZub2RlKTogdm9pZCB8IHN0cmluZyB7XG4gIGxldCBhcHBDb250YWluZXIgPSBudWxsO1xuXG4gIGlmIChpc05vZGVKcykge1xuICAgIGFwcENvbnRhaW5lciA9IHR5cGVvZiBjb250YWluZXIgPT09IFwic3RyaW5nXCIgPyBjcmVhdGVEb21FbGVtZW50KGNvbnRhaW5lciA9PT0gXCJzdmdcIiA/IFwic3ZnXCIgOiBcImRpdlwiLCBjb250YWluZXIgPT09IFwic3ZnXCIpIDogY29udGFpbmVyO1xuICB9IGVsc2Uge1xuICAgIGFwcENvbnRhaW5lciA9IHR5cGVvZiBjb250YWluZXIgPT09IFwic3RyaW5nXCIgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGNvbnRhaW5lcilbMF0gOiBjb250YWluZXI7XG4gIH1cblxuICBpZiAoIWFwcENvbnRhaW5lcikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNvbnRhaW5lciBub3QgZm91bmRcIik7XG4gIH1cblxuICBsZXQgdm5vZGVDb21wb25lbnQ6IFZub2RlQ29tcG9uZW50IHwgSVZub2RlO1xuXG4gIGlmIChpc1Zub2RlQ29tcG9uZW50KGNvbXBvbmVudCkpIHtcbiAgICB2bm9kZUNvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgfSBlbHNlIGlmIChpc0NvbXBvbmVudChjb21wb25lbnQpKSB7XG4gICAgdm5vZGVDb21wb25lbnQgPSB2KGNvbXBvbmVudCwge30pO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNvbXBvbmVudCBtdXN0IGJlIGEgVmFseXJpYW4gQ29tcG9uZW50IG9yIGEgVm5vZGUgY29tcG9uZW50XCIpO1xuICB9XG5cbiAgaWYgKGNvbXBvbmVudFtWYWx5cmlhblN5bWJvbF0pIHtcbiAgICB1bm1vdW50KGNvbXBvbmVudCk7XG4gIH0gZWxzZSB7XG4gICAgY29tcG9uZW50W1ZhbHlyaWFuU3ltYm9sXSA9IHtcbiAgICAgIGlzTW91bnRlZDogZmFsc2UsXG4gICAgICBldmVudExpc3RlbmVyTmFtZXM6IHt9LFxuICAgICAgb25DbGVhbnVwOiBbXSxcbiAgICAgIG9uTW91bnQ6IFtdLFxuICAgICAgb25VcGRhdGU6IFtdLFxuICAgICAgb25Vbm1vdW50OiBbXVxuICAgIH07XG4gICAgZnVuY3Rpb24gZXZlbnRMaXN0ZW5lcihlOiBFdmVudCkge1xuICAgICAgbGV0IGRvbSA9IGUudGFyZ2V0IGFzIERvbUVsZW1lbnQgJiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgbGV0IG5hbWUgPSBgdi1vbiR7ZS50eXBlfWA7XG4gICAgICB3aGlsZSAoZG9tKSB7XG4gICAgICAgIGlmIChkb21bbmFtZV0pIHtcbiAgICAgICAgICBkb21bbmFtZV0oZSwgZG9tKTtcbiAgICAgICAgICBpZiAoIWUuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgICAgdXBkYXRlKGNvbXBvbmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBkb20gPSBkb20ucGFyZW50Tm9kZSBhcyBEb21FbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICBjb21wb25lbnRbVmFseXJpYW5TeW1ib2xdLmV2ZW50TGlzdGVuZXIgPSBldmVudExpc3RlbmVyO1xuICB9XG5cbiAgY29tcG9uZW50W1ZhbHlyaWFuU3ltYm9sXS5jb21wb25lbnQgPSB2bm9kZUNvbXBvbmVudDtcbiAgY29tcG9uZW50W1ZhbHlyaWFuU3ltYm9sXS5jb250YWluZXIgPSBhcHBDb250YWluZXI7XG4gIGNvbXBvbmVudFtWYWx5cmlhblN5bWJvbF0ubWFpblZub2RlID0gZG9tVG9Wbm9kZShhcHBDb250YWluZXIpO1xuXG4gIC8vIHVwZGF0ZVxuICByZXR1cm4gdXBkYXRlKGNvbXBvbmVudCk7XG59XG5cbmZ1bmN0aW9uIGNhbGxDbGVhbnVwKHZhbHlyaWFuQXBwOiBWYWx5cmlhbkFwcCkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHlyaWFuQXBwLm9uQ2xlYW51cC5sZW5ndGg7IGkrKykge1xuICAgIHZhbHlyaWFuQXBwLm9uQ2xlYW51cFtpXSgpO1xuICB9XG4gIHZhbHlyaWFuQXBwLm9uQ2xlYW51cCA9IFtdO1xufVxuXG5mdW5jdGlvbiBjYWxsVW5tb3VudCh2YWx5cmlhbkFwcDogVmFseXJpYW5BcHApIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx5cmlhbkFwcC5vblVubW91bnQubGVuZ3RoOyBpKyspIHtcbiAgICB2YWx5cmlhbkFwcC5vblVubW91bnRbaV0oKTtcbiAgfVxuICB2YWx5cmlhbkFwcC5vblVubW91bnQgPSBbXTtcbn1cblxuZnVuY3Rpb24gY2FsbE1vdW50KHZhbHlyaWFuQXBwOiBWYWx5cmlhbkFwcCkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHlyaWFuQXBwLm9uTW91bnQubGVuZ3RoOyBpKyspIHtcbiAgICB2YWx5cmlhbkFwcC5vbk1vdW50W2ldKCk7XG4gIH1cbiAgdmFseXJpYW5BcHAub25Nb3VudCA9IFtdO1xufVxuXG5mdW5jdGlvbiBjYWxsVXBkYXRlKHZhbHlyaWFuQXBwOiBWYWx5cmlhbkFwcCkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHlyaWFuQXBwLm9uVXBkYXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFseXJpYW5BcHAub25VcGRhdGVbaV0oKTtcbiAgfVxuICB2YWx5cmlhbkFwcC5vblVwZGF0ZSA9IFtdO1xufVxuXG5mdW5jdGlvbiB1cGRhdGUoY29tcG9uZW50PzogVmFseXJpYW5Db21wb25lbnQgfCBJVm5vZGUpOiB2b2lkIHwgc3RyaW5nIHtcbiAgaWYgKGNvbXBvbmVudCAmJiBjb21wb25lbnRbVmFseXJpYW5TeW1ib2xdKSB7XG4gICAgbGV0IHZhbHlyaWFuQXBwID0gY29tcG9uZW50W1ZhbHlyaWFuU3ltYm9sXTtcbiAgICBjdXJyZW50LmFwcCA9IHZhbHlyaWFuQXBwO1xuICAgIHZhbHlyaWFuQXBwLm9uQ2xlYW51cC5sZW5ndGggJiYgY2FsbENsZWFudXAodmFseXJpYW5BcHApO1xuICAgIGxldCBvbGRWbm9kZTogVm5vZGVXaXRoRG9tIHwgbnVsbCA9IHZhbHlyaWFuQXBwLm1haW5Wbm9kZSBhcyBWbm9kZVdpdGhEb207XG4gICAgdmFseXJpYW5BcHAubWFpblZub2RlID0gbmV3IFZub2RlKHZhbHlyaWFuQXBwLm1haW5Wbm9kZS50YWcsIHZhbHlyaWFuQXBwLm1haW5Wbm9kZS5wcm9wcywgW3ZhbHlyaWFuQXBwLmNvbXBvbmVudF0pIGFzIFZub2RlV2l0aERvbTtcbiAgICB2YWx5cmlhbkFwcC5tYWluVm5vZGUuZG9tID0gb2xkVm5vZGUuZG9tO1xuICAgIHBhdGNoKHZhbHlyaWFuQXBwLm1haW5Wbm9kZSwgb2xkVm5vZGUsIHZhbHlyaWFuQXBwKTtcbiAgICBvbGRWbm9kZSA9IG51bGw7XG4gICAgaWYgKHZhbHlyaWFuQXBwLmlzTW91bnRlZCA9PT0gZmFsc2UpIHtcbiAgICAgIHZhbHlyaWFuQXBwLm9uTW91bnQubGVuZ3RoICYmIGNhbGxNb3VudCh2YWx5cmlhbkFwcCk7XG4gICAgICB2YWx5cmlhbkFwcC5pc01vdW50ZWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx5cmlhbkFwcC5vblVwZGF0ZS5sZW5ndGggJiYgY2FsbFVwZGF0ZSh2YWx5cmlhbkFwcCk7XG4gICAgfVxuXG4gICAgaWYgKGlzTm9kZUpzKSB7XG4gICAgICByZXR1cm4gdmFseXJpYW5BcHAubWFpblZub2RlLmRvbS5pbm5lckhUTUw7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVubW91bnQoY29tcG9uZW50PzogVmFseXJpYW5Db21wb25lbnQgfCBJVm5vZGUpOiB2b2lkIHwgc3RyaW5nIHtcbiAgaWYgKCFjb21wb25lbnQgfHwgIWNvbXBvbmVudFtWYWx5cmlhblN5bWJvbF0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgdmFseXJpYW5BcHAgPSBjb21wb25lbnRbVmFseXJpYW5TeW1ib2xdIGFzIE1vdW50ZWRWYWx5cmlhbkFwcDtcblxuICBpZiAodmFseXJpYW5BcHAuaXNNb3VudGVkKSB7XG4gICAgdmFseXJpYW5BcHAub25DbGVhbnVwLmxlbmd0aCAmJiBjYWxsQ2xlYW51cCh2YWx5cmlhbkFwcCk7XG4gICAgdmFseXJpYW5BcHAub25Vbm1vdW50Lmxlbmd0aCAmJiBjYWxsVW5tb3VudCh2YWx5cmlhbkFwcCk7XG4gICAgbGV0IG9sZFZub2RlOiBWbm9kZVdpdGhEb20gfCBudWxsID0gdmFseXJpYW5BcHAubWFpblZub2RlIGFzIFZub2RlV2l0aERvbTtcbiAgICB2YWx5cmlhbkFwcC5tYWluVm5vZGUgPSBuZXcgVm5vZGUodmFseXJpYW5BcHAubWFpblZub2RlLnRhZywgdmFseXJpYW5BcHAubWFpblZub2RlLnByb3BzLCBbXSkgYXMgVm5vZGVXaXRoRG9tO1xuICAgIHZhbHlyaWFuQXBwLm1haW5Wbm9kZS5kb20gPSBvbGRWbm9kZS5kb207XG4gICAgdmFseXJpYW5BcHAubWFpblZub2RlLmlzU1ZHID0gb2xkVm5vZGUuaXNTVkc7XG4gICAgcGF0Y2godmFseXJpYW5BcHAubWFpblZub2RlLCBvbGRWbm9kZSwgdmFseXJpYW5BcHApO1xuICAgIG9sZFZub2RlID0gbnVsbDtcblxuICAgIGlmIChpc05vZGVKcykge1xuICAgICAgcmV0dXJuIHZhbHlyaWFuQXBwLm1haW5Wbm9kZS5kb20uaW5uZXJIVE1MO1xuICAgIH1cblxuICAgICh2YWx5cmlhbkFwcCBhcyBhbnkpID0gbnVsbDtcbiAgICBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KGNvbXBvbmVudCwgVmFseXJpYW5TeW1ib2wpO1xuICB9XG59XG5cbmxldCBlbXB0eVZub2RlID0gbmV3IFZub2RlKFwiX19lbXB0eV9fXCIsIHt9LCBbXSk7XG5cbmZ1bmN0aW9uIG9ucmVtb3ZlKHZub2RlOiBJVm5vZGUpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgIHZub2RlLmNoaWxkcmVuW2ldLnRhZyAhPT0gVGV4dFN0cmluZyAmJiBvbnJlbW92ZSh2bm9kZS5jaGlsZHJlbltpXSk7XG4gIH1cblxuICB2bm9kZS5wcm9wcy5vbnJlbW92ZSAmJiB2bm9kZS5wcm9wcy5vbnJlbW92ZSh2bm9kZSk7XG59XG5cbmZ1bmN0aW9uIHNoYXJlZFNldEF0dHJpYnV0ZShwcm9wOiBzdHJpbmcsIHZhbHVlOiBhbnksIHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKTogdm9pZCB8IGJvb2xlYW4ge1xuICAvLyBJdCBpcyBhIHJlc2VydmVkIHByb3BcbiAgaWYgKHJlc2VydmVkUHJvcHNbcHJvcF0pIHtcbiAgICAvLyBJZiBpdCBpcyBhIGRpcmVjdGl2ZSBuYW1lIGNhbGwgdGhlIGRpcmVjdGl2ZVxuICAgIGlmIChkaXJlY3RpdmVzW3Byb3BdKSB7XG4gICAgICByZXR1cm4gZGlyZWN0aXZlc1twcm9wXSh2bm9kZS5wcm9wc1twcm9wXSwgdm5vZGUsIG9sZFZub2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBJdCBpcyBub3QgYSByZXNlcnZlZCBwcm9wIHNvIHdlIGFkZCBpdCB0byB0aGUgZG9tXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGxldCB2YWx5cmlhbkFwcCA9IGN1cnJlbnQuYXBwIGFzIE1vdW50ZWRWYWx5cmlhbkFwcDtcbiAgICBpZiAocHJvcCBpbiB2YWx5cmlhbkFwcC5ldmVudExpc3RlbmVyTmFtZXMgPT09IGZhbHNlKSB7XG4gICAgICB2YWx5cmlhbkFwcC5ldmVudExpc3RlbmVyTmFtZXNbcHJvcF0gPSB0cnVlO1xuICAgICAgdmFseXJpYW5BcHAuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIocHJvcC5zbGljZSgyKSwgdmFseXJpYW5BcHAuZXZlbnRMaXN0ZW5lcik7XG4gICAgfVxuICAgIHZub2RlLmRvbVtgdi0ke3Byb3B9YF0gPSB2YWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocHJvcCBpbiB2bm9kZS5kb20gJiYgdm5vZGUuaXNTVkcgPT09IGZhbHNlKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuICAgIGlmICh2bm9kZS5kb21bcHJvcF0gIT0gdmFsdWUpIHtcbiAgICAgIHZub2RlLmRvbVtwcm9wXSA9IHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBVc2Ugc2V0IGF0dHJpYnV0ZVxuICBpZiAoIW9sZFZub2RlIHx8IG9sZFZub2RlLnByb3BzW3Byb3BdICE9PSB2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHZub2RlLmRvbS5yZW1vdmVBdHRyaWJ1dGUocHJvcCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZub2RlLmRvbS5zZXRBdHRyaWJ1dGUocHJvcCwgdmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRBdHRyaWJ1dGUobmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCB2bm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSkge1xuICB2bm9kZS5wcm9wc1tuYW1lXSA9IHZhbHVlO1xuXG4gIHNoYXJlZFNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSwgdm5vZGUsIG9sZFZub2RlKTtcbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlcyh2bm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSkge1xuICBmb3IgKGxldCBwcm9wIGluIHZub2RlLnByb3BzKSB7XG4gICAgaWYgKHNoYXJlZFNldEF0dHJpYnV0ZShwcm9wLCB2bm9kZS5wcm9wc1twcm9wXSwgdm5vZGUsIG9sZFZub2RlKSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAob2xkVm5vZGUpIHtcbiAgICBmb3IgKGxldCBwcm9wIGluIG9sZFZub2RlLnByb3BzKSB7XG4gICAgICBpZiAocHJvcCBpbiB2bm9kZS5wcm9wcyA9PT0gZmFsc2UgJiYgdHlwZW9mIG9sZFZub2RlLnByb3BzW3Byb3BdICE9PSBcImZ1bmN0aW9uXCIgJiYgcHJvcCBpbiByZXNlcnZlZFByb3BzID09PSBmYWxzZSkge1xuICAgICAgICBpZiAocHJvcCBpbiBvbGRWbm9kZS5kb20gJiYgdm5vZGUuaXNTVkcgPT09IGZhbHNlKSB7XG4gICAgICAgICAgb2xkVm5vZGUuZG9tW3Byb3BdID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvbGRWbm9kZS5kb20ucmVtb3ZlQXR0cmlidXRlKHByb3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5mdW5jdGlvbiBwYXRjaChuZXdWbm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZTogVm5vZGVXaXRoRG9tIHwgSVZub2RlID0gZW1wdHlWbm9kZSwgdmFseXJpYW5BcHA6IE1vdW50ZWRWYWx5cmlhbkFwcCkge1xuICBjdXJyZW50LnZub2RlID0gbmV3Vm5vZGU7XG4gIGN1cnJlbnQub2xkVm5vZGUgPSBvbGRWbm9kZSA9PT0gZW1wdHlWbm9kZSA/IFVuZCA6IChvbGRWbm9kZSBhcyBWbm9kZVdpdGhEb20pO1xuICBsZXQgbmV3VHJlZSA9IG5ld1Zub2RlLmNoaWxkcmVuO1xuICBsZXQgb2xkVHJlZSA9IG9sZFZub2RlLmNoaWxkcmVuO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbmV3VHJlZS5sZW5ndGg7IGkrKykge1xuICAgIGxldCBjaGlsZFZub2RlID0gbmV3VHJlZVtpXTtcbiAgICBpZiAoY2hpbGRWbm9kZSBpbnN0YW5jZW9mIFZub2RlKSB7XG4gICAgICBpZiAoY2hpbGRWbm9kZS50YWcgIT09IFRleHRTdHJpbmcpIHtcbiAgICAgICAgaWYgKGNoaWxkVm5vZGUudGFnID09PSBDb21wb25lbnRTdHJpbmcpIHtcbiAgICAgICAgICBsZXQgY29tcG9uZW50ID0gY2hpbGRWbm9kZS5jb21wb25lbnQgYXMgVmFseXJpYW5Db21wb25lbnQ7XG4gICAgICAgICAgY3VycmVudC5jb21wb25lbnQgPSBjb21wb25lbnQ7XG4gICAgICAgICAgbGV0IHJlc3VsdCA9IChcInZpZXdcIiBpbiBjb21wb25lbnQgPyBjb21wb25lbnQudmlldyA6IGNvbXBvbmVudCkuY2FsbChjb21wb25lbnQsIGNoaWxkVm5vZGUucHJvcHMsIC4uLmNoaWxkVm5vZGUuY2hpbGRyZW4pO1xuXG4gICAgICAgICAgbmV3VHJlZS5zcGxpY2UoaS0tLCAxLCByZXN1bHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNoaWxkVm5vZGUuaXNTVkcgPSBuZXdWbm9kZS5pc1NWRyB8fCBjaGlsZFZub2RlLnRhZyA9PT0gXCJzdmdcIjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGRWbm9kZSkpIHtcbiAgICAgIG5ld1RyZWUuc3BsaWNlKGktLSwgMSwgLi4uY2hpbGRWbm9kZSk7XG4gICAgfSBlbHNlIGlmIChjaGlsZFZub2RlID09PSBudWxsIHx8IGNoaWxkVm5vZGUgPT09IFVuZCkge1xuICAgICAgbmV3VHJlZS5zcGxpY2UoaS0tLCAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3VHJlZVtpXSA9IG5ldyBWbm9kZShUZXh0U3RyaW5nLCB7fSwgW10pO1xuICAgICAgbmV3VHJlZVtpXS5ub2RlVmFsdWUgPSBjaGlsZFZub2RlO1xuICAgIH1cbiAgfVxuXG4gIGxldCBvbGRUcmVlTGVuZ3RoID0gb2xkVHJlZS5sZW5ndGg7XG4gIGxldCBuZXdUcmVlTGVuZ3RoID0gbmV3VHJlZS5sZW5ndGg7XG5cbiAgLy8gSWYgbmV3IHRyZWUgaXMgZW1wdHksIHJlbW92ZSBhbGwgb2xkIG5vZGVzXG4gIGlmIChuZXdUcmVlTGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvbGRUcmVlTGVuZ3RoOyBpKyspIHtcbiAgICAgIG9sZFRyZWVbaV0udGFnICE9PSBUZXh0U3RyaW5nICYmIG9ucmVtb3ZlKG9sZFRyZWVbaV0pO1xuICAgIH1cblxuICAgIG5ld1Zub2RlLmRvbS50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gSWYgdGhlIHRyZWUgaXMga2V5ZWQgbGlzdCBhbmQgaXMgbm90IGZpcnN0IHJlbmRlciBhbmQgb2xkIHRyZWUgaXMga2V5ZWQgbGlzdCB0b29cbiAgaWYgKG9sZFRyZWVMZW5ndGggJiYgXCJrZXlcIiBpbiBuZXdUcmVlWzBdLnByb3BzICYmIFwia2V5XCIgaW4gb2xkVHJlZVswXS5wcm9wcykge1xuICAgIGxldCBvbGRLZXllZExpc3Q6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9sZFRyZWVMZW5ndGg7IGkrKykge1xuICAgICAgb2xkS2V5ZWRMaXN0W29sZFRyZWVbaV0ucHJvcHMua2V5XSA9IGk7XG4gICAgfVxuXG4gICAgbGV0IG5ld0tleWVkTGlzdDogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmV3VHJlZUxlbmd0aDsgaSsrKSB7XG4gICAgICBuZXdLZXllZExpc3RbbmV3VHJlZVtpXS5wcm9wcy5rZXldID0gaTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5ld1RyZWVMZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGNoaWxkVm5vZGUgPSBuZXdUcmVlW2ldO1xuICAgICAgbGV0IG9sZENoaWxkVm5vZGUgPSBvbGRUcmVlW29sZEtleWVkTGlzdFtjaGlsZFZub2RlLnByb3BzLmtleV1dO1xuICAgICAgbGV0IHNob3VsZFBhdGNoID0gdHJ1ZTtcblxuICAgICAgaWYgKG9sZENoaWxkVm5vZGUpIHtcbiAgICAgICAgY2hpbGRWbm9kZS5kb20gPSBvbGRDaGlsZFZub2RlLmRvbTtcbiAgICAgICAgaWYgKFwidi1vbmNlXCIgaW4gY2hpbGRWbm9kZS5wcm9wcyB8fCAoY2hpbGRWbm9kZS5wcm9wcy5zaG91bGR1cGRhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5zaG91bGR1cGRhdGUoY2hpbGRWbm9kZSwgb2xkQ2hpbGRWbm9kZSkgPT09IGZhbHNlKSkge1xuICAgICAgICAgIC8vIHNraXAgdGhpcyBwYXRjaFxuICAgICAgICAgIGNoaWxkVm5vZGUuY2hpbGRyZW4gPSBvbGRDaGlsZFZub2RlLmNoaWxkcmVuO1xuICAgICAgICAgIHNob3VsZFBhdGNoID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0QXR0cmlidXRlcyhjaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgICBpZiAodmFseXJpYW5BcHAuaXNNb3VudGVkKSB7XG4gICAgICAgICAgICBjaGlsZFZub2RlLnByb3BzLm9udXBkYXRlICYmIGNoaWxkVm5vZGUucHJvcHMub251cGRhdGUoY2hpbGRWbm9kZSwgb2xkQ2hpbGRWbm9kZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZShjaGlsZFZub2RlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoaWxkVm5vZGUuZG9tID0gY3JlYXRlRG9tRWxlbWVudChjaGlsZFZub2RlLnRhZywgY2hpbGRWbm9kZS5pc1NWRyk7XG4gICAgICAgIHNldEF0dHJpYnV0ZXMoY2hpbGRWbm9kZSk7XG4gICAgICAgIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZShjaGlsZFZub2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5ld1Zub2RlLmRvbS5jaGlsZE5vZGVzW2ldID09PSBVbmQpIHtcbiAgICAgICAgbmV3Vm5vZGUuZG9tLmFwcGVuZENoaWxkKGNoaWxkVm5vZGUuZG9tKTtcbiAgICAgIH0gZWxzZSBpZiAobmV3Vm5vZGUuZG9tLmNoaWxkTm9kZXNbaV0gIT09IGNoaWxkVm5vZGUuZG9tKSB7XG4gICAgICAgIG9sZFRyZWVbaV0gJiYgbmV3S2V5ZWRMaXN0W29sZFRyZWVbaV0ucHJvcHMua2V5XSA9PT0gVW5kICYmIG9ucmVtb3ZlKG9sZFRyZWVbaV0pO1xuICAgICAgICBuZXdWbm9kZS5kb20ucmVwbGFjZUNoaWxkKGNoaWxkVm5vZGUuZG9tLCBuZXdWbm9kZS5kb20uY2hpbGROb2Rlc1tpXSk7XG4gICAgICB9XG5cbiAgICAgIHNob3VsZFBhdGNoICYmIHBhdGNoKGNoaWxkVm5vZGUsIG9sZENoaWxkVm5vZGUsIHZhbHlyaWFuQXBwKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgdGhlIHJlc3Qgb2YgdGhlIGNoaWxkcmVuLCB3ZSBzaG91bGQgcmVtb3ZlIHRoZW1cbiAgICBmb3IgKGxldCBpID0gbmV3VHJlZUxlbmd0aDsgaSA8IG9sZFRyZWVMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG5ld0tleWVkTGlzdFtvbGRUcmVlW2ldLnByb3BzLmtleV0gPT09IFVuZCkge1xuICAgICAgICBsZXQgb2xkQ2hpbGRWbm9kZSA9IG9sZFRyZWVbaV07XG4gICAgICAgIG9ucmVtb3ZlKG9sZENoaWxkVm5vZGUpO1xuICAgICAgICBvbGRDaGlsZFZub2RlLmRvbS5wYXJlbnROb2RlICYmIG9sZENoaWxkVm5vZGUuZG9tLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQob2xkQ2hpbGRWbm9kZS5kb20pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIG5ldyB0cmVlIGFuZCBvbGQgdHJlZSBoYXZlIG1vcmUgdGhhbiBvbmUgY2hpbGQsIHdlIHNob3VsZCB1cGRhdGUgdGhlIGRvbVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG5ld1RyZWVMZW5ndGg7IGkrKykge1xuICAgIGxldCBuZXdDaGlsZFZub2RlID0gbmV3VHJlZVtpXTtcblxuICAgIC8vIE9sZCBjaGlsZCBleGlzdHNcbiAgICBpZiAoaSA8IG9sZFRyZWVMZW5ndGgpIHtcbiAgICAgIGxldCBvbGRDaGlsZFZub2RlID0gb2xkVHJlZVtpXTtcbiAgICAgIC8vIE5ldyBjaGlsZCBpcyBhIHRleHQgbm9kZVxuICAgICAgaWYgKG5ld0NoaWxkVm5vZGUudGFnID09PSBUZXh0U3RyaW5nKSB7XG4gICAgICAgIC8vIE9sZCBjaGlsZCBpcyBhIHRleHQgbm9kZVxuICAgICAgICBpZiAob2xkQ2hpbGRWbm9kZS50YWcgPT09IFRleHRTdHJpbmcpIHtcbiAgICAgICAgICBuZXdDaGlsZFZub2RlLmRvbSA9IG9sZENoaWxkVm5vZGUuZG9tO1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcbiAgICAgICAgICBpZiAobmV3Q2hpbGRWbm9kZS5kb20ubm9kZVZhbHVlICE9IG5ld0NoaWxkVm5vZGUubm9kZVZhbHVlKSB7XG4gICAgICAgICAgICBuZXdDaGlsZFZub2RlLmRvbS5ub2RlVmFsdWUgPSBuZXdDaGlsZFZub2RlLm5vZGVWYWx1ZSBhcyBzdHJpbmc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT2xkIGNoaWxkIGlzIGEgbm9ybWFsIG5vZGVcbiAgICAgICAgbmV3Q2hpbGRWbm9kZS5kb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShuZXdDaGlsZFZub2RlLm5vZGVWYWx1ZSBhcyBzdHJpbmcpIGFzIHVua25vd24gYXMgRG9tRWxlbWVudDtcbiAgICAgICAgb25yZW1vdmUob2xkQ2hpbGRWbm9kZSk7XG4gICAgICAgIG5ld1Zub2RlLmRvbS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGRWbm9kZS5kb20sIG9sZENoaWxkVm5vZGUuZG9tKTtcblxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gTmV3IGNoaWxkIGlzIGEgbm9ybWFsIG5vZGVcbiAgICAgIC8vIE9sZCBjaGlsZCBpcyB0aGUgc2FtZSB0eXBlIGFzIG5ldyBjaGlsZFxuICAgICAgaWYgKG9sZENoaWxkVm5vZGUudGFnID09PSBuZXdDaGlsZFZub2RlLnRhZykge1xuICAgICAgICBuZXdDaGlsZFZub2RlLmRvbSA9IG9sZENoaWxkVm5vZGUuZG9tO1xuICAgICAgICAvLyBJZiB3ZSBoYXZlIGEgdi1vbmNlIGRpcmVjdGl2ZSBvciBhIHNob3VsZHVwZGF0ZSBtZXRob2QgdGhhdCByZXR1cm5zIGZhbHNlLCB3ZSBza2lwIHRoZSB1cGRhdGVcbiAgICAgICAgaWYgKG5ld0NoaWxkVm5vZGUucHJvcHNbXCJ2LW9uY2VcIl0gfHwgKG5ld0NoaWxkVm5vZGUucHJvcHMuc2hvdWxkdXBkYXRlICYmIG5ld0NoaWxkVm5vZGUucHJvcHMuc2hvdWxkdXBkYXRlKG5ld0NoaWxkVm5vZGUsIG9sZENoaWxkVm5vZGUpID09PSBmYWxzZSkpIHtcbiAgICAgICAgICBuZXdDaGlsZFZub2RlLmNoaWxkcmVuID0gb2xkQ2hpbGRWbm9kZS5jaGlsZHJlbjtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdlIHVwZGF0ZSB0aGUgZG9tIGVsZW1lbnRcbiAgICAgICAgc2V0QXR0cmlidXRlcyhuZXdDaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgaWYgKHZhbHlyaWFuQXBwLmlzTW91bnRlZCkge1xuICAgICAgICAgIG5ld0NoaWxkVm5vZGUucHJvcHMub251cGRhdGUgJiYgbmV3Q2hpbGRWbm9kZS5wcm9wcy5vbnVwZGF0ZShuZXdDaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdDaGlsZFZub2RlLnByb3BzLm9uY3JlYXRlICYmIG5ld0NoaWxkVm5vZGUucHJvcHMub25jcmVhdGUobmV3Q2hpbGRWbm9kZSk7XG4gICAgICAgIH1cblxuICAgICAgICBwYXRjaChuZXdDaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlLCB2YWx5cmlhbkFwcCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBPbGQgY2hpbGQgaXMgb2YgYSBkaWZmZXJlbnQgdHlwZSB0aGFuIG5ldyBjaGlsZFxuICAgICAgbmV3Q2hpbGRWbm9kZS5kb20gPSBjcmVhdGVEb21FbGVtZW50KG5ld0NoaWxkVm5vZGUudGFnLCBuZXdDaGlsZFZub2RlLmlzU1ZHKTtcbiAgICAgIHNldEF0dHJpYnV0ZXMobmV3Q2hpbGRWbm9kZSk7XG4gICAgICBvbGRDaGlsZFZub2RlLnRhZyAhPT0gVGV4dFN0cmluZyAmJiBvbnJlbW92ZShvbGRDaGlsZFZub2RlKTtcbiAgICAgIG5ld0NoaWxkVm5vZGUucHJvcHMub25jcmVhdGUgJiYgbmV3Q2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZShuZXdDaGlsZFZub2RlKTtcbiAgICAgIG5ld1Zub2RlLmRvbS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGRWbm9kZS5kb20sIG9sZENoaWxkVm5vZGUuZG9tKTtcbiAgICAgIHBhdGNoKG5ld0NoaWxkVm5vZGUsIGVtcHR5Vm5vZGUsIHZhbHlyaWFuQXBwKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIE9sZCBjaGlsZCBkb2VzIG5vdCBleGlzdHNcbiAgICAvLyBOZXcgY2hpbGQgaXMgYSB0ZXh0IG5vZGVcbiAgICBpZiAobmV3Q2hpbGRWbm9kZS50YWcgPT09IFRleHRTdHJpbmcpIHtcbiAgICAgIG5ld0NoaWxkVm5vZGUuZG9tID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobmV3Q2hpbGRWbm9kZS5ub2RlVmFsdWUgYXMgc3RyaW5nKSBhcyB1bmtub3duIGFzIERvbUVsZW1lbnQ7XG4gICAgICBuZXdWbm9kZS5kb20uYXBwZW5kQ2hpbGQobmV3Q2hpbGRWbm9kZS5kb20pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gTmV3IGNoaWxkIGlzIGEgbm9ybWFsIG5vZGVcbiAgICBuZXdDaGlsZFZub2RlLmRvbSA9IGNyZWF0ZURvbUVsZW1lbnQobmV3Q2hpbGRWbm9kZS50YWcsIG5ld0NoaWxkVm5vZGUuaXNTVkcpO1xuICAgIHNldEF0dHJpYnV0ZXMobmV3Q2hpbGRWbm9kZSk7XG4gICAgbmV3Vm5vZGUuZG9tLmFwcGVuZENoaWxkKG5ld0NoaWxkVm5vZGUuZG9tKTtcbiAgICBuZXdDaGlsZFZub2RlLnByb3BzLm9uY3JlYXRlICYmIG5ld0NoaWxkVm5vZGUucHJvcHMub25jcmVhdGUobmV3Q2hpbGRWbm9kZSk7XG4gICAgcGF0Y2gobmV3Q2hpbGRWbm9kZSwgZW1wdHlWbm9kZSwgdmFseXJpYW5BcHApO1xuICB9XG5cbiAgLy8gRm9yIHRoZSByZXN0IG9mIHRoZSBjaGlsZHJlbiwgd2Ugc2hvdWxkIHJlbW92ZSB0aGVtXG4gIGZvciAobGV0IGkgPSBuZXdUcmVlTGVuZ3RoOyBpIDwgb2xkVHJlZUxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IG9sZENoaWxkVm5vZGUgPSBvbGRUcmVlW2ldO1xuICAgIG9sZENoaWxkVm5vZGUudGFnICE9PSBUZXh0U3RyaW5nICYmIG9ucmVtb3ZlKG9sZENoaWxkVm5vZGUpO1xuICAgIG9sZENoaWxkVm5vZGUuZG9tLnBhcmVudE5vZGUgJiYgb2xkQ2hpbGRWbm9kZS5kb20ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvbGRDaGlsZFZub2RlLmRvbSk7XG4gIH1cbn1cblxuLyoqKiBEaXJlY3RpdmVzICoqKi9cblxuZnVuY3Rpb24gZGlyZWN0aXZlKG5hbWU6IHN0cmluZywgZGlyZWN0aXZlOiBEaXJlY3RpdmUpIHtcbiAgbGV0IGZ1bGxOYW1lID0gYHYtJHtuYW1lfWA7XG4gIGRpcmVjdGl2ZXNbZnVsbE5hbWVdID0gZGlyZWN0aXZlO1xuICByZXNlcnZlZFByb3BzW2Z1bGxOYW1lXSA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIGhpZGVEaXJlY3RpdmUodGVzdDogYm9vbGVhbik6IERpcmVjdGl2ZSB7XG4gIHJldHVybiAoYm9vbDogYm9vbGVhbiwgdm5vZGU6IElWbm9kZSwgb2xkVm5vZGU/OiBJVm5vZGUpID0+IHtcbiAgICBsZXQgdmFsdWUgPSB0ZXN0ID8gYm9vbCA6ICFib29sO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgbGV0IG5ld2RvbSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiXCIpO1xuICAgICAgaWYgKG9sZFZub2RlICYmIG9sZFZub2RlLmRvbSAmJiBvbGRWbm9kZS5kb20ucGFyZW50Tm9kZSkge1xuICAgICAgICBvbGRWbm9kZS50YWcgIT09IFRleHRTdHJpbmcgJiYgb25yZW1vdmUob2xkVm5vZGUpO1xuICAgICAgICBvbGRWbm9kZS5kb20ucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3ZG9tLCBvbGRWbm9kZS5kb20pO1xuICAgICAgfVxuICAgICAgdm5vZGUudGFnID0gVGV4dFN0cmluZztcbiAgICAgIHZub2RlLmNoaWxkcmVuID0gW107XG4gICAgICB2bm9kZS5wcm9wcyA9IHt9O1xuICAgICAgdm5vZGUuZG9tID0gbmV3ZG9tIGFzIHVua25vd24gYXMgRG9tRWxlbWVudDtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG59XG5cbmNvbnN0IGRpcmVjdGl2ZXM6IERpcmVjdGl2ZXMgPSB7XG4gIFwidi1pZlwiOiBoaWRlRGlyZWN0aXZlKGZhbHNlKSxcbiAgXCJ2LXVubGVzc1wiOiBoaWRlRGlyZWN0aXZlKHRydWUpLFxuICBcInYtZm9yXCI6IChzZXQ6IHVua25vd25bXSwgdm5vZGU6IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIHZub2RlLmNoaWxkcmVuID0gc2V0Lm1hcCh2bm9kZS5jaGlsZHJlblswXSk7XG4gIH0sXG4gIFwidi1zaG93XCI6IChib29sOiBib29sZWFuLCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgKHZub2RlLmRvbSBhcyB1bmtub3duIGFzIHsgc3R5bGU6IHsgZGlzcGxheTogc3RyaW5nIH0gfSkuc3R5bGUuZGlzcGxheSA9IGJvb2wgPyBcIlwiIDogXCJub25lXCI7XG4gIH0sXG4gIFwidi1jbGFzc1wiOiAoY2xhc3NlczogeyBbeDogc3RyaW5nXTogYm9vbGVhbiB9LCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBjbGFzc2VzKSB7XG4gICAgICAodm5vZGUuZG9tIGFzIERvbUVsZW1lbnQpLmNsYXNzTGlzdC50b2dnbGUobmFtZSwgY2xhc3Nlc1tuYW1lXSk7XG4gICAgfVxuICB9LFxuICBcInYtaHRtbFwiOiAoaHRtbDogc3RyaW5nLCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgdm5vZGUuY2hpbGRyZW4gPSBbdHJ1c3QoaHRtbCldO1xuICB9LFxuICBcInYtbW9kZWxcIjogKFttb2RlbCwgcHJvcGVydHksIGV2ZW50XTogYW55W10sIHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGxldCBoYW5kbGVyO1xuICAgIGlmICh2bm9kZS5uYW1lID09PSBcImlucHV0XCIpIHtcbiAgICAgIGV2ZW50ID0gZXZlbnQgfHwgXCJvbmlucHV0XCI7XG4gICAgICBzd2l0Y2ggKHZub2RlLnByb3BzLnR5cGUpIHtcbiAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6IHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eV0pKSB7XG4gICAgICAgICAgICBoYW5kbGVyID0gKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgIGxldCB2YWwgPSAoZS50YXJnZXQgYXMgRG9tRWxlbWVudCAmIFJlY29yZDxzdHJpbmcsIGFueT4pLnZhbHVlO1xuICAgICAgICAgICAgICBsZXQgaWR4ID0gbW9kZWxbcHJvcGVydHldLmluZGV4T2YodmFsKTtcbiAgICAgICAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0ucHVzaCh2YWwpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XS5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhbHVlID0gbW9kZWxbcHJvcGVydHldLmluZGV4T2Yodm5vZGUuZG9tLnZhbHVlKSAhPT0gLTE7XG4gICAgICAgICAgfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gdm5vZGUucHJvcHMpIHtcbiAgICAgICAgICAgIGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChtb2RlbFtwcm9wZXJ0eV0gPT09IHZub2RlLnByb3BzLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldID0gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0gPSB2bm9kZS5wcm9wcy52YWx1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhbHVlID0gbW9kZWxbcHJvcGVydHldID09PSB2bm9kZS5wcm9wcy52YWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlciA9ICgpID0+IChtb2RlbFtwcm9wZXJ0eV0gPSAhbW9kZWxbcHJvcGVydHldKTtcbiAgICAgICAgICAgIHZhbHVlID0gbW9kZWxbcHJvcGVydHldO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIsIHZhbHVlLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJyYWRpb1wiOiB7XG4gICAgICAgICAgc2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiLCBtb2RlbFtwcm9wZXJ0eV0gPT09IHZub2RlLmRvbS52YWx1ZSwgdm5vZGUsIG9sZFZub2RlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgc2V0QXR0cmlidXRlKFwidmFsdWVcIiwgbW9kZWxbcHJvcGVydHldLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2bm9kZS5uYW1lID09PSBcInNlbGVjdFwiKSB7XG4gICAgICBldmVudCA9IGV2ZW50IHx8IFwib25jbGlja1wiO1xuICAgICAgaWYgKHZub2RlLnByb3BzLm11bHRpcGxlKSB7XG4gICAgICAgIGhhbmRsZXIgPSAoZTogRXZlbnQgJiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB7XG4gICAgICAgICAgbGV0IHZhbCA9IChlLnRhcmdldCBhcyBEb21FbGVtZW50ICYgUmVjb3JkPHN0cmluZywgYW55PikudmFsdWU7XG4gICAgICAgICAgaWYgKGUuY3RybEtleSkge1xuICAgICAgICAgICAgbGV0IGlkeCA9IG1vZGVsW3Byb3BlcnR5XS5pbmRleE9mKHZhbCk7XG4gICAgICAgICAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0ucHVzaCh2YWwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnNwbGljZShpZHgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0uc3BsaWNlKDAsIG1vZGVsW3Byb3BlcnR5XS5sZW5ndGgpO1xuICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnB1c2godmFsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkOiBJVm5vZGUpID0+IHtcbiAgICAgICAgICBpZiAoY2hpbGQudGFnID09PSBcIm9wdGlvblwiKSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBcInZhbHVlXCIgaW4gY2hpbGQucHJvcHMgPyBjaGlsZC5wcm9wcy52YWx1ZSA6IGNoaWxkLmNoaWxkcmVuLmpvaW4oXCJcIikudHJpbSgpO1xuICAgICAgICAgICAgY2hpbGQucHJvcHMuc2VsZWN0ZWQgPSBtb2RlbFtwcm9wZXJ0eV0uaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2bm9kZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogSVZub2RlKSA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkLnRhZyA9PT0gXCJvcHRpb25cIikge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gXCJ2YWx1ZVwiIGluIGNoaWxkLnByb3BzID8gY2hpbGQucHJvcHMudmFsdWUgOiBjaGlsZC5jaGlsZHJlbi5qb2luKFwiXCIpLnRyaW0oKTtcbiAgICAgICAgICAgIGNoaWxkLnByb3BzLnNlbGVjdGVkID0gdmFsdWUgPT09IG1vZGVsW3Byb3BlcnR5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodm5vZGUubmFtZSA9PT0gXCJ0ZXh0YXJlYVwiKSB7XG4gICAgICBldmVudCA9IGV2ZW50IHx8IFwib25pbnB1dFwiO1xuICAgICAgdm5vZGUuY2hpbGRyZW4gPSBbbW9kZWxbcHJvcGVydHldXTtcbiAgICB9XG5cbiAgICBpZiAoIXZub2RlLnByb3BzW2V2ZW50XSkge1xuICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgIGhhbmRsZXIgPSAoZTogRXZlbnQpID0+IChtb2RlbFtwcm9wZXJ0eV0gPSAoZS50YXJnZXQgYXMgRG9tRWxlbWVudCAmIFJlY29yZDxzdHJpbmcsIGFueT4pLnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHNldEF0dHJpYnV0ZShldmVudCwgaGFuZGxlciwgdm5vZGUsIG9sZFZub2RlKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKiogUGx1Z2lucyAqKiovXG5jb25zdCBwbHVnaW5zID0gbmV3IE1hcDxQbHVnaW4sIGFueT4oKTtcblxuZnVuY3Rpb24gdXNlKHBsdWdpbjogUGx1Z2luLCBvcHRpb25zPzogUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgYW55Pik6IHZvaWQgfCBhbnkge1xuICBpZiAocGx1Z2lucy5oYXMocGx1Z2luKSkge1xuICAgIHJldHVybiBwbHVnaW5zLmdldChwbHVnaW4pO1xuICB9XG5cbiAgbGV0IHJlc3VsdCA9IHBsdWdpbih2LCBvcHRpb25zKTtcbiAgcGx1Z2lucy5zZXQocGx1Z2luLCByZXN1bHQpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKioqIEh5cGVyc2NyaXB0ICoqKi9cblxuZXhwb3J0IGNvbnN0IHY6IFZhbHlyaWFuID0gZnVuY3Rpb24gdih0YWdPckNvbXBvbmVudDogc3RyaW5nIHwgVmFseXJpYW5Db21wb25lbnQsIHByb3BzOiBQcm9wcywgLi4uY2hpbGRyZW46IENoaWxkcmVuKTogSVZub2RlIHwgVm5vZGVDb21wb25lbnQge1xuICBpZiAodHlwZW9mIHRhZ09yQ29tcG9uZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIG5ldyBWbm9kZSh0YWdPckNvbXBvbmVudCwgcHJvcHMgfHwge30sIGNoaWxkcmVuKTtcbiAgfVxuXG4gIGNvbnN0IHZub2RlID0gbmV3IFZub2RlKFwiX19jb21wb25lbnRfX1wiLCBwcm9wcyB8fCB7fSwgY2hpbGRyZW4pO1xuICB2bm9kZS5jb21wb25lbnQgPSB0YWdPckNvbXBvbmVudDtcbiAgcmV0dXJuIHZub2RlIGFzIFZub2RlQ29tcG9uZW50O1xufTtcblxudi5mcmFnbWVudCA9IChwcm9wczogUHJvcHMsIC4uLmNoaWxkcmVuOiBDaGlsZHJlbik6IENoaWxkcmVuID0+IHtcbiAgcmV0dXJuIGNoaWxkcmVuO1xufTtcblxuLyoqKiBWIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgKioqL1xuLy8gVGhpcyBpcyBpbnRlbmRlZCB0byBtYWtlIHRoZSBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzIGF2YWlsYWJsZSBmb3IgcGx1Z2luc1xudi5jdXJyZW50ID0gY3VycmVudDtcblxudi5kaXJlY3RpdmVzID0gZGlyZWN0aXZlcztcblxudi5yZXNlcnZlZFByb3BzID0gcmVzZXJ2ZWRQcm9wcztcblxudi5pc1Zub2RlID0gaXNWbm9kZTtcbnYuaXNDb21wb25lbnQgPSBpc0NvbXBvbmVudDtcbnYuaXNWbm9kZUNvbXBvbmVudCA9IGlzVm5vZGVDb21wb25lbnQ7XG5cbnYuaXNOb2RlSnMgPSBpc05vZGVKcztcbnYudHJ1c3QgPSB0cnVzdDtcblxudi5vbkNsZWFudXAgPSBvbkNsZWFudXA7XG52Lm9uVW5tb3VudCA9IG9uVW5tb3VudDtcbnYub25Nb3VudCA9IG9uTW91bnQ7XG52Lm9uVXBkYXRlID0gb25VcGRhdGU7XG5cbnYubW91bnQgPSBtb3VudDtcbnYudW5tb3VudCA9IHVubW91bnQ7XG52LnVwZGF0ZSA9IHVwZGF0ZTtcblxudi5zZXRBdHRyaWJ1dGUgPSBzZXRBdHRyaWJ1dGU7XG52LmRpcmVjdGl2ZSA9IGRpcmVjdGl2ZTtcbnYudXNlID0gdXNlO1xuIl19 \ No newline at end of file diff --git a/dist/valyrian.min.js b/dist/valyrian.min.js deleted file mode 100644 index 5e65e94..0000000 --- a/dist/valyrian.min.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var e=class{name;props;children;dom;onCleanup;isSVG;processed;constructor(e,o,n){this.props=o,this.children=n,this.name=e}},o=class{dom;nodeValue;constructor(e){this.nodeValue=e}},n=class{component;props;children;constructor(e,o,n){this.props=o,this.children=n,this.component=e}},t="undefined"==typeof window||"undefined"!=typeof global;function d(e,o=!1){return o?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}function r(n){let t={};[].forEach.call(n.attributes,e=>t[e.nodeName]=e.nodeValue);let d=new e(n.nodeName.toLowerCase(),t,[]);d.dom=n;for(let e=0,t=n.childNodes.length;e{let o=d("div");return o.innerHTML=e.trim(),[].map.call(o.childNodes,e=>r(e))};(t?global:window).v=function p(){let l=(o,t,...d)=>"string"==typeof o?new e(o,t||{},d):new n(o,t||{},d);l.fragment=(e,o)=>o,l.isMounted=!1,l.isNode=t;let s=["key","data","v-once","oncreate","onupdate","onremove","onbeforeupdate"];l.reservedWords=s,l.trust=i;let c={parentVnode:void 0,oldParentVnode:void 0,component:void 0};l.current=c;let a=new Map;l.usePlugin=(e,o={})=>!a.has(e)&&a.set(e,!0)&&e(l,o);let m=[];l.onCleanup=e=>{let o=l.current.parentVnode;o.onCleanup||(o.onCleanup=[]),o.onCleanup.push(e),-1===m.indexOf(o)&&m.push(o)};let u=null,f=()=>"",h=f,v=[];function V(e){let o=e.target,n=`v-on${e.type}`;for(;o;){if(o[n])return o[n](e,o),void(e.defaultPrevented||l.update());o=o.parentNode}}function g(e,o,n){if(-1!==s.indexOf(e)){if(e in M)return M[e](o.props[e],o,n)}else"function"==typeof o.props[e]?(-1===v.indexOf(e)&&(u.addEventListener(e.slice(2),V),v.push(e)),o.dom[`v-${e}`]=o.props[e]):e in o.dom&&!o.isSVG?o.dom[e]!=o.props[e]&&(o.dom[e]=o.props[e]):(void 0===n||o.props[e]!==n.props[e])&&(!1===o.props[e]?o.dom.removeAttribute(e):o.dom.setAttribute(e,o.props[e]))}function y(e,o){for(let n in e.props)if(!1===g(n,e,o))return}function N(e,o){for(let n in o.props)!(n in e.props)&&"function"!=typeof o.props[n]&&-1===s.indexOf(n)&&(n in e.dom?e.dom[n]=null:e.dom.removeAttribute(n))}l.updateProperty=g;let w=o=>{for(let n=0,t=o.children.length;n0&&p[d-1].nodeValue?(p[d-1].nodeValue+=r,p.splice(d--,1)):r instanceof o||(p[d]=new o(String(r)))}let a=p.length;if(0===a){if(s>0){for(let o=s;o--;)i[o]instanceof e&&w(i[o]);t.dom.textContent=""}}else if(s&&p[0]instanceof e&&"key"in p[0].props){let o;if(i[0]instanceof e&&"key"in i[0].props)o=i.map(e=>e.props.key);else{for(let o=s;o--;)i[o]instanceof e&&w(i[o]);t.dom.textContent="",o=[]}let n=p.map(e=>e.props.key),r=Math.max(a,o.length);for(let s=0;s=a;--o)i[o]instanceof e&&w(i[o]),i[o].dom.parentNode&&t.dom.removeChild(i[o].dom)}t.children=p}let x=null,S=null;l.unMount=()=>{h=f;let e=l.update();return l.isMounted=!1,u=null,e},l.update=(o,...n)=>{if(x&&((()=>{for(let e=m.length;e--;)for(let o of m[e].onCleanup)o();m=[]})(),S=x,x=new e(x.name,x.props,[l(h,o,...n)]),x.dom=S.dom,x.isSVG=S.isSVG,C(x,S),l.isMounted=!0,l.isNode))return x.dom.innerHTML},l.mount=(e,o,n,...i)=>(l.isMounted&&l.unMount(),u=t?"string"==typeof e?d(e,"svg"===e):e:"string"==typeof e?document.querySelectorAll(e)[0]:e,null!==u&&(x=r(u),x.isSVG="svg"===x.name,S=x,h=o),l.update(n,...i));let M={};l.directive=(e,o)=>{let n=`v-${e}`;-1===s.indexOf(n)&&(s.push(n),M[n]=o)};let b=o=>(n,t,d)=>{if(o?n:!n){let o=document.createTextNode("");return d&&d.dom&&d.dom.parentNode&&(d instanceof e&&w(d),d.dom.parentNode.replaceChild(o,d.dom)),t.name="#text",t.children=[],t.props={},t.dom=o,!1}};return l.directive("if",b(!1)),l.directive("unless",b(!0)),l.directive("for",(e,o)=>{o.children=e.map(o.children[0])}),l.directive("show",(e,o)=>{o.dom.style.display=e?"":"none"}),l.directive("class",(e,o)=>{for(let n in e)o.dom.classList.toggle(n,e[n])}),l.directive("html",(e,o)=>{o.children=[i(e)]}),l.newInstance=p,l}()})(); \ No newline at end of file diff --git a/dist/valyrian.min.js.map b/dist/valyrian.min.js.map deleted file mode 100644 index f9679e9..0000000 --- a/dist/valyrian.min.js.map +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2xpYi9pbmRleC50cyJdLCJuYW1lcyI6WyJwIiwibmFtZSIsInByb3BzIiwiY2hpbGRyZW4iLCJkb20iLCJvbkNsZWFudXAiLCJpc1NWRyIsInByb2Nlc3NlZCIsImNvbnN0cnVjdG9yIiwiYSIsInUiLCJjIiwidGhpcyIsIngiLCJub2RlVmFsdWUiLCJNIiwiY29tcG9uZW50IiwiUyIsIndpbmRvdyIsImdsb2JhbCIsImIiLCJkIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50TlMiLCJjcmVhdGVFbGVtZW50IiwiVSIsImZvckVhY2giLCJjYWxsIiwiYXR0cmlidXRlcyIsIm5vZGVOYW1lIiwidG9Mb3dlckNhc2UiLCJ5IiwiY2hpbGROb2RlcyIsImxlbmd0aCIsIm5vZGVUeXBlIiwicHVzaCIsIk4iLCJGIiwiaW5uZXJIVE1MIiwidHJpbSIsIm1hcCIsInYiLCJIIiwiZSIsIm8iLCJ0IiwiZnJhZ21lbnQiLCJpc01vdW50ZWQiLCJpc05vZGUiLCJyZXNlcnZlZFdvcmRzIiwidHJ1c3QiLCJwYXJlbnRWbm9kZSIsIm9sZFBhcmVudFZub2RlIiwiY3VycmVudCIsIk1hcCIsInVzZVBsdWdpbiIsImhhcyIsInNldCIsImluZGV4T2YiLCJnIiwidyIsIlQiLCJMIiwiVyIsInRhcmdldCIsInR5cGUiLCJkZWZhdWx0UHJldmVudGVkIiwidXBkYXRlIiwicGFyZW50Tm9kZSIsIkciLCJPIiwiYWRkRXZlbnRMaXN0ZW5lciIsInNsaWNlIiwicmVtb3ZlQXR0cmlidXRlIiwic2V0QXR0cmlidXRlIiwiRSIsIlAiLCJ1cGRhdGVQcm9wZXJ0eSIsIlYiLCJvbnJlbW92ZSIsIkQiLCJsIiwiQyIsInIiLCJuIiwic3BsaWNlIiwiQXJyYXkiLCJpc0FycmF5IiwidmlldyIsIlN0cmluZyIsInRleHRDb250ZW50IiwiaSIsImtleSIsIm0iLCJNYXRoIiwibWF4IiwicyIsImgiLCJBIiwib25iZWZvcmV1cGRhdGUiLCJvbnVwZGF0ZSIsIm9uY3JlYXRlIiwiYXBwZW5kQ2hpbGQiLCJyZXBsYWNlQ2hpbGQiLCJyZW1vdmVDaGlsZCIsImNyZWF0ZVRleHROb2RlIiwiZiIsImsiLCJ1bk1vdW50IiwibW91bnQiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZGlyZWN0aXZlIiwiUiIsInN0eWxlIiwiZGlzcGxheSIsImNsYXNzTGlzdCIsInRvZ2dsZSIsIm5ld0luc3RhbmNlIl0sIm1hcHBpbmdzIjoiTUFvREEsSUFBQUEsRUFBQSxNQUNFQyxLQUNBQyxNQUNBQyxTQUNBQyxJQUNBQyxVQUNBQyxNQUNBQyxVQUVBQyxZQUFZQyxFQUFjQyxFQUFjQyxHQUN0Q0MsS0FBS1YsTUFBUVEsRUFDYkUsS0FBS1QsU0FBV1EsRUFDaEJDLEtBQUtYLEtBQU9RLElBU2hCSSxFQUFBLE1BQ0VULElBQ0FVLFVBRUFOLFlBQVlDLEdBQ1ZHLEtBQUtFLFVBQVlMLElBVXJCTSxFQUFBLE1BQ0VDLFVBQ0FkLE1BQ0FDLFNBRUFLLFlBQVlDLEVBQThCQyxFQUFjQyxHQUN0REMsS0FBS1YsTUFBUVEsRUFDYkUsS0FBS1QsU0FBV1EsRUFDaEJDLEtBQUtJLFVBQVlQLElBdUJqQlEsRUFBMkIsb0JBQVhDLFFBQTRDLG9CQUFYQyxPQUdyRCxTQUFBQyxFQUF1QkMsRUFBaUJaLEdBQWlCLEdBQ3ZELE9BQU9BLEVBQVFhLFNBQVNDLGdCQUFnQiw2QkFBOEJGLEdBQVdDLFNBQVNFLGNBQWNILEdBSTFHLFNBQUFJLEVBQW9CSixHQUNsQixJQUFJWixFQUFlLEdBQ25CLEdBQUdpQixRQUFRQyxLQUFLTixFQUFJTyxXQUFhakIsR0FBZ0JGLEVBQU1FLEVBQUtrQixVQUFZbEIsRUFBS0csV0FFN0UsSUFBSUosRUFBZSxJQUFJVixFQUFNcUIsRUFBSVEsU0FBU0MsY0FBZXJCLEVBQU8sSUFDaEVDLEVBQU1OLElBQU1pQixFQUVaLElBQUEsSUFBU1YsRUFBSSxFQUFHb0IsRUFBSVYsRUFBSVcsV0FBV0MsT0FBUXRCLEVBQUlvQixFQUFHcEIsSUFDaEQsR0FBbUMsSUFBL0JVLEVBQUlXLFdBQVdyQixHQUFHdUIsU0FDcEJ4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QVNtRixlQUFlLElBQ3JDLE9BQUl4QixHQUFXQSxFQUFRN0UsS0FBTzZFLEVBQVE3RSxJQUFJZ0UsYUFDeENhLGFBQW1CakYsR0FBUzhFLEVBQVdHLEdBQ3ZDQSxFQUFRN0UsSUFBSWdFLFdBQVdtQyxhQUFhOUQsRUFBUXdDLEVBQVE3RSxNQUV0RHlDLEVBQU01QyxLQUFPLFFBQ2I0QyxFQUFNMUMsU0FBVyxHQUNqQjBDLEVBQU0zQyxNQUFRLEdBQ2QyQyxFQUFNekMsSUFBTXFDLEdBQ0wsSUFJWCxPQUFBcEIsRUFBRTBGLFVBQVUsS0FBTUMsR0FBYyxJQUNoQzNGLEVBQUUwRixVQUFVLFNBQVVDLEdBQWMsSUFDcEMzRixFQUFFMEYsVUFBVSxNQUFPLENBQUNwRSxFQUFnQkMsS0FDbENBLEVBQU16QyxTQUFXd0MsRUFBSUgsSUFBSUksRUFBTXpDLFNBQVMsTUFFMUNrQixFQUFFMEYsVUFBVSxPQUFRLENBQUNwRSxFQUFlQyxLQUNqQ0EsRUFBTXhDLElBQXVDNkcsTUFBTUMsUUFBVXZFLEVBQU8sR0FBSyxTQUU1RXRCLEVBQUUwRixVQUFVLFFBQVMsQ0FBQ3BFLEVBQW1DQyxLQUN2RCxJQUFBLElBQVNDLEtBQVFGLEVBQ2RDLEVBQU14QyxJQUFtQitHLFVBQVVDLE9BQU92RSxFQUFNRixFQUFRRSxNQUc3RHhCLEVBQUUwRixVQUFVLE9BQVEsQ0FBQ3BFLEVBQWNDLEtBQ2pDQSxFQUFNekMsU0FBVyxDQUFDa0MsRUFBTU0sTUFHMUJ0QixFQUFFZ0csWUFBYzNFLEVBRVRyQixFQUdzRHFCIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuLyogZXNsaW50LWRpc2FibGUgc29uYXJqcy9jb2duaXRpdmUtY29tcGxleGl0eSAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5cbnR5cGUgVm5vZGVPclVua25vd24gPSBWbm9kZUNvbXBvbmVudCB8IFZub2RlIHwgVGV4dFZub2RlIHwgYW55O1xuXG50eXBlIERvbUF0dHJpYnV0ZSA9IHsgbm9kZU5hbWU6IHN0cmluZzsgbm9kZVZhbHVlOiBzdHJpbmcgfTtcblxudHlwZSBEb21FbGVtZW50ID0gKEhUTUxFbGVtZW50IHwgU1ZHRWxlbWVudCkgJiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG50eXBlIFByb3BzID0ge1xuICBrZXk/OiBzdHJpbmcgfCBudW1iZXI7XG4gIGRhdGE/OiBzdHJpbmc7XG4gIG9uY3JlYXRlPzogeyAodm5vZGU6IFZub2RlKTogbmV2ZXIgfTtcbiAgb251cGRhdGU/OiB7ICh2bm9kZTogVm5vZGUsIG9sZFZub2RlOiBWbm9kZSB8IFRleHRWbm9kZSk6IG5ldmVyIH07XG4gIG9ucmVtb3ZlPzogeyAob2xkVm5vZGU6IFZub2RlKTogbmV2ZXIgfTtcbiAgb25iZWZvcmV1cGRhdGU/OiB7ICh2bm9kZTogVm5vZGUsIG9sZFZub2RlOiBWbm9kZSB8IFRleHRWbm9kZSk6IHVuZGVmaW5lZCB8IGJvb2xlYW4gfTtcbn0gJiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG50eXBlIENvbXBvbmVudCA9IChwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsLCBjaGlsZHJlbj86IFZub2RlT3JVbmtub3duKSA9PiBWbm9kZU9yVW5rbm93biB8IFZub2RlT3JVbmtub3duW107XG5cbnR5cGUgVmFseXJpYW5Db21wb25lbnQgPVxuICB8IENvbXBvbmVudFxuICB8IChSZWNvcmQ8c3RyaW5nLCBhbnk+ICYge1xuICAgICAgdmlldzogQ29tcG9uZW50O1xuICAgIH0pO1xuXG50eXBlIEN1cnJlbnQgPSB7IHBhcmVudFZub2RlPzogVm5vZGU7IG9sZFBhcmVudFZub2RlPzogVm5vZGU7IGNvbXBvbmVudD86IFZub2RlQ29tcG9uZW50IH07XG5cbmludGVyZmFjZSBQbHVnaW4ge1xuICAodjogVmFseXJpYW4sIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogbmV2ZXI7XG59XG5cbmludGVyZmFjZSBEaXJlY3RpdmUge1xuICAodmFsdWU6IGFueSwgdm5vZGU6IFZub2RlLCBvbGRWbm9kZT86IFZub2RlIHwgVGV4dFZub2RlKTogdm9pZCB8IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBWYWx5cmlhbkV2ZW50SGFuZGxlciB7XG4gIChhOiBFdmVudCwgZG9tOiBEb21FbGVtZW50KTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIFZub2RlIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwcm9wczogUHJvcHM7XG4gIGNoaWxkcmVuOiBWbm9kZU9yVW5rbm93bltdO1xuICBkb20/OiBEb21FbGVtZW50O1xuICBvbkNsZWFudXA/OiBGdW5jdGlvbkNvbnN0cnVjdG9yW107XG4gIGlzU1ZHPzogYm9vbGVhbjtcbiAgcHJvY2Vzc2VkPzogYm9vbGVhbjtcbn1cblxuY2xhc3MgVm5vZGUgaW1wbGVtZW50cyBWbm9kZSB7XG4gIG5hbWU6IHN0cmluZztcbiAgcHJvcHM6IFByb3BzO1xuICBjaGlsZHJlbjogVm5vZGVPclVua25vd25bXTtcbiAgZG9tPzogRG9tRWxlbWVudDtcbiAgb25DbGVhbnVwPzogRnVuY3Rpb25Db25zdHJ1Y3RvcltdO1xuICBpc1NWRz86IGJvb2xlYW47XG4gIHByb2Nlc3NlZD86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCBwcm9wczogUHJvcHMsIGNoaWxkcmVuOiBWbm9kZU9yVW5rbm93bikge1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgfVxufVxuXG5pbnRlcmZhY2UgVGV4dFZub2RlIHtcbiAgZG9tPzogVGV4dDtcbiAgbm9kZVZhbHVlOiBzdHJpbmc7XG59XG5cbmNsYXNzIFRleHRWbm9kZSBpbXBsZW1lbnRzIFRleHRWbm9kZSB7XG4gIGRvbT86IFRleHQ7XG4gIG5vZGVWYWx1ZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKG5vZGVWYWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5ub2RlVmFsdWUgPSBub2RlVmFsdWU7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFZub2RlQ29tcG9uZW50IHtcbiAgY29tcG9uZW50OiBWYWx5cmlhbkNvbXBvbmVudDtcbiAgcHJvcHM6IFByb3BzO1xuICBjaGlsZHJlbjogVm5vZGVPclVua25vd25bXTtcbn1cblxuY2xhc3MgVm5vZGVDb21wb25lbnQgaW1wbGVtZW50cyBWbm9kZUNvbXBvbmVudCB7XG4gIGNvbXBvbmVudDogVmFseXJpYW5Db21wb25lbnQ7XG4gIHByb3BzOiBQcm9wcztcbiAgY2hpbGRyZW46IFZub2RlT3JVbmtub3duW107XG5cbiAgY29uc3RydWN0b3IoY29tcG9uZW50OiBWYWx5cmlhbkNvbXBvbmVudCwgcHJvcHM6IFByb3BzLCBjaGlsZHJlbjogVm5vZGVPclVua25vd25bXSkge1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnQ7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFZhbHlyaWFuIHtcbiAgKHRhZ09yQ29tcG9uZW50OiBzdHJpbmcgfCBWYWx5cmlhbkNvbXBvbmVudCwgcHJvcHM/OiBQcm9wcyB8IG51bGwsIGNoaWxkcmVuPzogVm5vZGVPclVua25vd24pOiBWbm9kZSB8IFZub2RlQ29tcG9uZW50O1xuICBmcmFnbWVudDogKHByb3BzOiBQcm9wcywgY2hpbGRyZW46IFZub2RlT3JVbmtub3duW10pID0+IFZub2RlT3JVbmtub3duW107XG4gIGlzTW91bnRlZDogYm9vbGVhbjtcbiAgaXNOb2RlOiBib29sZWFuO1xuICByZXNlcnZlZFdvcmRzOiBzdHJpbmdbXTtcbiAgY3VycmVudDogQ3VycmVudDtcbiAgdHJ1c3Q6IChodG1sU3RyaW5nOiBzdHJpbmcpID0+IFZub2RlW107XG4gIHVzZVBsdWdpbjogKHBsdWdpbjogUGx1Z2luLCBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB2b2lkO1xuICBvbkNsZWFudXA6IChjYWxsYmFjazogdHlwZW9mIEZ1bmN0aW9uKSA9PiB2b2lkO1xuICB1cGRhdGVQcm9wZXJ0eTogKG5hbWU6IHN0cmluZywgbmV3Vm5vZGU6IFZub2RlICYgeyBkb206IERvbUVsZW1lbnQgfSwgb2xkTm9kZTogVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9KSA9PiB2b2lkO1xuICB1cGRhdGU6IChwcm9wcz86IFByb3BzIHwgbnVsbCwgLi4uY2hpbGRyZW46IFZub2RlT3JVbmtub3duKSA9PiBzdHJpbmcgfCB2b2lkO1xuICBtb3VudDogKGNvbnRhaW5lcjogc3RyaW5nIHwgRG9tRWxlbWVudCwgY29tcG9uZW50OiBWYWx5cmlhbkNvbXBvbmVudCwgcHJvcHM/OiBQcm9wcyB8IG51bGwsIC4uLmNoaWxkcmVuOiBWbm9kZU9yVW5rbm93bltdKSA9PiBzdHJpbmcgfCB2b2lkO1xuICB1bk1vdW50OiAoKSA9PiBzdHJpbmcgfCBib29sZWFuIHwgdm9pZDtcbiAgZGlyZWN0aXZlOiAoZGlyZWN0aXZlOiBzdHJpbmcsIGhhbmRsZXI6IERpcmVjdGl2ZSkgPT4gdm9pZDtcbiAgbmV3SW5zdGFuY2U6ICgpID0+IFZhbHlyaWFuO1xuICBbeDogc3RyaW5nXTogYW55O1xufVxuXG5sZXQgaXNOb2RlID0gdHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIiB8fCB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiO1xuXG4vLyBDcmVhdGUgTm9kZSBlbGVtZW50XG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHRhZ05hbWU6IHN0cmluZywgaXNTVkc6IGJvb2xlYW4gPSBmYWxzZSk6IERvbUVsZW1lbnQge1xuICByZXR1cm4gaXNTVkcgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCB0YWdOYW1lKSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG59XG5cbi8vIFRyYW5zZm9ybXMgYSBET00gbm9kZSB0byBhIFZOb2RlXG5mdW5jdGlvbiBkb21Ub1Zub2RlKGRvbTogRG9tRWxlbWVudCk6IFZub2RlIHtcbiAgbGV0IHByb3BzOiBQcm9wcyA9IHt9O1xuICBbXS5mb3JFYWNoLmNhbGwoZG9tLmF0dHJpYnV0ZXMsIChwcm9wOiBBdHRyKSA9PiAocHJvcHNbcHJvcC5ub2RlTmFtZV0gPSBwcm9wLm5vZGVWYWx1ZSkpO1xuXG4gIGxldCB2bm9kZTogVm5vZGUgPSBuZXcgVm5vZGUoZG9tLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksIHByb3BzLCBbXSk7XG4gIHZub2RlLmRvbSA9IGRvbTtcblxuICBmb3IgKGxldCBpID0gMCwgbCA9IGRvbS5jaGlsZE5vZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChkb20uY2hpbGROb2Rlc1tpXS5ub2RlVHlwZSA9PT0gMSkge1xuICAgICAgdm5vZGUuY2hpbGRyZW4ucHVzaChkb21Ub1Zub2RlKGRvbS5jaGlsZE5vZGVzW2ldIGFzIERvbUVsZW1lbnQpKTtcbiAgICB9IGVsc2UgaWYgKGRvbS5jaGlsZE5vZGVzW2ldLm5vZGVUeXBlID09PSAzKSB7XG4gICAgICBsZXQgdGV4dFZub2RlID0gbmV3IFRleHRWbm9kZShkb20uY2hpbGROb2Rlc1tpXS5ub2RlVmFsdWUgfHwgXCJcIik7XG4gICAgICB0ZXh0Vm5vZGUuZG9tID0gZG9tLmNoaWxkTm9kZXNbaV0gYXMgdW5rbm93biBhcyBUZXh0O1xuICAgICAgdm5vZGUuY2hpbGRyZW4ucHVzaCh0ZXh0Vm5vZGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdm5vZGU7XG59XG5cbmNvbnN0IHRydXN0ID0gKGh0bWxTdHJpbmc6IHN0cmluZykgPT4ge1xuICBsZXQgZGl2ID0gY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgZGl2LmlubmVySFRNTCA9IGh0bWxTdHJpbmcudHJpbSgpO1xuXG4gIHJldHVybiBbXS5tYXAuY2FsbChkaXYuY2hpbGROb2RlcywgKGl0ZW0pID0+IGRvbVRvVm5vZGUoaXRlbSkpIGFzIFZub2RlW107XG59O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxpbmVzLXBlci1mdW5jdGlvblxuZnVuY3Rpb24gdmFseXJpYW4oKTogVmFseXJpYW4ge1xuICBjb25zdCB2OiBWYWx5cmlhbiA9ICh0YWdPckNvbXBvbmVudCwgcHJvcHMsIC4uLmNoaWxkcmVuKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB0YWdPckNvbXBvbmVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIG5ldyBWbm9kZSh0YWdPckNvbXBvbmVudCwgcHJvcHMgfHwge30sIGNoaWxkcmVuKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBWbm9kZUNvbXBvbmVudCh0YWdPckNvbXBvbmVudCwgcHJvcHMgfHwge30sIGNoaWxkcmVuKTtcbiAgICB9XG4gIH07XG5cbiAgdi5mcmFnbWVudCA9IChwcm9wczogUHJvcHMsIHZub2RlczogVm5vZGVPclVua25vd25bXSkgPT4ge1xuICAgIHJldHVybiB2bm9kZXM7XG4gIH07XG5cbiAgdi5pc01vdW50ZWQgPSBmYWxzZTtcbiAgdi5pc05vZGUgPSBpc05vZGU7XG4gIGNvbnN0IHJlc2VydmVkV29yZHMgPSBbXCJrZXlcIiwgXCJkYXRhXCIsIFwidi1vbmNlXCIsIFwib25jcmVhdGVcIiwgXCJvbnVwZGF0ZVwiLCBcIm9ucmVtb3ZlXCIsIFwib25iZWZvcmV1cGRhdGVcIl07XG4gIHYucmVzZXJ2ZWRXb3JkcyA9IHJlc2VydmVkV29yZHM7XG4gIHYudHJ1c3QgPSB0cnVzdDtcblxuICBjb25zdCBjdXJyZW50OiBDdXJyZW50ID0ge1xuICAgIHBhcmVudFZub2RlOiB1bmRlZmluZWQsXG4gICAgb2xkUGFyZW50Vm5vZGU6IHVuZGVmaW5lZCxcbiAgICBjb21wb25lbnQ6IHVuZGVmaW5lZFxuICB9O1xuICB2LmN1cnJlbnQgPSBjdXJyZW50O1xuXG4gIGNvbnN0IHBsdWdpbnMgPSBuZXcgTWFwKCk7XG5cbiAgdi51c2VQbHVnaW4gPSAocGx1Z2luOiBQbHVnaW4sIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSkgPT4gIXBsdWdpbnMuaGFzKHBsdWdpbikgJiYgcGx1Z2lucy5zZXQocGx1Z2luLCB0cnVlKSAmJiBwbHVnaW4odiBhcyBWYWx5cmlhbiwgb3B0aW9ucyk7XG5cbiAgbGV0IHZub2Rlc1RvQ2xlYW51cDogVm5vZGVbXSA9IFtdO1xuXG4gIHYub25DbGVhbnVwID0gKGNhbGxiYWNrOiBGdW5jdGlvbkNvbnN0cnVjdG9yKSA9PiB7XG4gICAgbGV0IHBhcmVudFZub2RlID0gdi5jdXJyZW50LnBhcmVudFZub2RlIGFzIFZub2RlO1xuICAgIGlmICghcGFyZW50Vm5vZGUub25DbGVhbnVwKSB7XG4gICAgICBwYXJlbnRWbm9kZS5vbkNsZWFudXAgPSBbXSBhcyBGdW5jdGlvbkNvbnN0cnVjdG9yW107XG4gICAgfVxuXG4gICAgcGFyZW50Vm5vZGUub25DbGVhbnVwLnB1c2goY2FsbGJhY2spO1xuXG4gICAgaWYgKHZub2Rlc1RvQ2xlYW51cC5pbmRleE9mKHBhcmVudFZub2RlKSA9PT0gLTEpIHtcbiAgICAgIHZub2Rlc1RvQ2xlYW51cC5wdXNoKHBhcmVudFZub2RlKTtcbiAgICB9XG4gIH07XG5cbiAgbGV0IGNsZWFudXBWbm9kZXMgPSAoKSA9PiB7XG4gICAgZm9yIChsZXQgbCA9IHZub2Rlc1RvQ2xlYW51cC5sZW5ndGg7IGwtLTsgKSB7XG4gICAgICBmb3IgKGxldCBjYWxsYmFjayBvZiB2bm9kZXNUb0NsZWFudXBbbF0ub25DbGVhbnVwIGFzIEZ1bmN0aW9uQ29uc3RydWN0b3JbXSkge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH1cbiAgICB2bm9kZXNUb0NsZWFudXAgPSBbXTtcbiAgfTtcblxuICBsZXQgbWFpbkNvbnRhaW5lcjogRG9tRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBsZXQgZW1wdHlDb21wb25lbnQ6IFZhbHlyaWFuQ29tcG9uZW50ID0gKCkgPT4gXCJcIjtcbiAgbGV0IG1vdW50ZWRDb21wb25lbnQ6IFZhbHlyaWFuQ29tcG9uZW50ID0gZW1wdHlDb21wb25lbnQ7XG5cbiAgY29uc3QgYXR0YWNoZWRMaXN0ZW5lcnM6IHN0cmluZ1tdID0gW107XG4gIGZ1bmN0aW9uIGV2ZW50TGlzdGVuZXIoZTogRXZlbnQpIHtcbiAgICBsZXQgZG9tID0gZS50YXJnZXQgYXMgRG9tRWxlbWVudDtcbiAgICBsZXQgbmFtZSA9IGB2LW9uJHtlLnR5cGV9YDtcbiAgICB3aGlsZSAoZG9tKSB7XG4gICAgICBpZiAoZG9tW25hbWVdKSB7XG4gICAgICAgIChkb21bbmFtZV0gYXMgVmFseXJpYW5FdmVudEhhbmRsZXIpKGUsIGRvbSk7XG4gICAgICAgIGlmICghZS5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgdi51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkb20gPSBkb20ucGFyZW50Tm9kZSBhcyBEb21FbGVtZW50O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVByb3BlcnR5KHByb3A6IHN0cmluZywgbmV3Vm5vZGU6IFZub2RlICYgeyBkb206IERvbUVsZW1lbnQgfSwgb2xkVm5vZGU/OiBWbm9kZSk6IHZvaWQgfCBib29sZWFuIHtcbiAgICBpZiAocmVzZXJ2ZWRXb3Jkcy5pbmRleE9mKHByb3ApICE9PSAtMSkge1xuICAgICAgaWYgKHByb3AgaW4gZGlyZWN0aXZlcykge1xuICAgICAgICByZXR1cm4gZGlyZWN0aXZlc1twcm9wXShuZXdWbm9kZS5wcm9wc1twcm9wXSwgbmV3Vm5vZGUsIG9sZFZub2RlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBuZXdWbm9kZS5wcm9wc1twcm9wXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBpZiAoYXR0YWNoZWRMaXN0ZW5lcnMuaW5kZXhPZihwcm9wKSA9PT0gLTEpIHtcbiAgICAgICAgKG1haW5Db250YWluZXIgYXMgRG9tRWxlbWVudCkuYWRkRXZlbnRMaXN0ZW5lcihwcm9wLnNsaWNlKDIpLCBldmVudExpc3RlbmVyKTtcbiAgICAgICAgYXR0YWNoZWRMaXN0ZW5lcnMucHVzaChwcm9wKTtcbiAgICAgIH1cbiAgICAgIG5ld1Zub2RlLmRvbVtgdi0ke3Byb3B9YF0gPSBuZXdWbm9kZS5wcm9wc1twcm9wXTtcbiAgICB9IGVsc2UgaWYgKHByb3AgaW4gbmV3Vm5vZGUuZG9tICYmICFuZXdWbm9kZS5pc1NWRykge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuICAgICAgaWYgKG5ld1Zub2RlLmRvbVtwcm9wXSAhPSBuZXdWbm9kZS5wcm9wc1twcm9wXSkge1xuICAgICAgICBuZXdWbm9kZS5kb21bcHJvcF0gPSBuZXdWbm9kZS5wcm9wc1twcm9wXTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9sZFZub2RlID09PSB1bmRlZmluZWQgfHwgbmV3Vm5vZGUucHJvcHNbcHJvcF0gIT09IG9sZFZub2RlLnByb3BzW3Byb3BdKSB7XG4gICAgICBpZiAobmV3Vm5vZGUucHJvcHNbcHJvcF0gPT09IGZhbHNlKSB7XG4gICAgICAgIG5ld1Zub2RlLmRvbS5yZW1vdmVBdHRyaWJ1dGUocHJvcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdWbm9kZS5kb20uc2V0QXR0cmlidXRlKHByb3AsIG5ld1Zub2RlLnByb3BzW3Byb3BdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdi51cGRhdGVQcm9wZXJ0eSA9IHVwZGF0ZVByb3BlcnR5O1xuXG4gIC8vIFVwZGF0ZSBhIFZub2RlLmRvbSBIVE1MRWxlbWVudCB3aXRoIG5ldyBWbm9kZSBwcm9wcyB0aGF0IGFyZSBkaWZmZXJlbnQgZnJvbSBvbGQgVm5vZGUgcHJvcHNcbiAgZnVuY3Rpb24gdXBkYXRlUHJvcGVydGllcyhuZXdWbm9kZTogVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9LCBvbGRWbm9kZT86IFZub2RlKTogdm9pZCB7XG4gICAgZm9yIChsZXQgcHJvcCBpbiBuZXdWbm9kZS5wcm9wcykge1xuICAgICAgaWYgKHVwZGF0ZVByb3BlcnR5KHByb3AsIG5ld1Zub2RlLCBvbGRWbm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVQcm9wZXJ0aWVzKG5ld1Zub2RlOiBWbm9kZSAmIHsgZG9tOiBEb21FbGVtZW50IH0sIG9sZFZub2RlOiBWbm9kZSkge1xuICAgIGZvciAobGV0IG5hbWUgaW4gb2xkVm5vZGUucHJvcHMpIHtcbiAgICAgIGlmIChuYW1lIGluIG5ld1Zub2RlLnByb3BzID09PSBmYWxzZSAmJiB0eXBlb2Ygb2xkVm5vZGUucHJvcHNbbmFtZV0gIT09IFwiZnVuY3Rpb25cIiAmJiByZXNlcnZlZFdvcmRzLmluZGV4T2YobmFtZSkgPT09IC0xKSB7XG4gICAgICAgIGlmIChuYW1lIGluIG5ld1Zub2RlLmRvbSkge1xuICAgICAgICAgIG5ld1Zub2RlLmRvbVtuYW1lXSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3Vm5vZGUuZG9tLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNhbGxSZW1vdmUgPSAodm5vZGU6IFZub2RlKSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSB2bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZub2RlLmNoaWxkcmVuW2ldIGluc3RhbmNlb2YgVm5vZGUgJiYgY2FsbFJlbW92ZSh2bm9kZS5jaGlsZHJlbltpXSk7XG4gICAgfVxuXG4gICAgdm5vZGUucHJvcHMub25yZW1vdmUgJiYgdm5vZGUucHJvcHMub25yZW1vdmUodm5vZGUpO1xuICB9O1xuICAvLyBQYXRjaCBhIERPTSBub2RlIHdpdGggYSBuZXcgVk5vZGUgdHJlZVxuICBmdW5jdGlvbiBwYXRjaChuZXdQYXJlbnRWbm9kZTogVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9LCBvbGRQYXJlbnRWbm9kZT86IFZub2RlICYgeyBkb206IERvbUVsZW1lbnQgfSk6IHZvaWQge1xuICAgIGxldCBvbGRUcmVlID0gb2xkUGFyZW50Vm5vZGU/LmNoaWxkcmVuIHx8IFtdO1xuICAgIGxldCBuZXdUcmVlID0gbmV3UGFyZW50Vm5vZGUuY2hpbGRyZW47XG4gICAgbGV0IG9sZFRyZWVMZW5ndGggPSBvbGRUcmVlLmxlbmd0aDtcblxuICAgIGN1cnJlbnQucGFyZW50Vm5vZGUgPSBuZXdQYXJlbnRWbm9kZTtcbiAgICBjdXJyZW50Lm9sZFBhcmVudFZub2RlID0gb2xkUGFyZW50Vm5vZGU7XG5cbiAgICAvLyBGbGF0IG5ld1RyZWVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5ld1RyZWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBjaGlsZFZub2RlID0gbmV3VHJlZVtpXTtcblxuICAgICAgaWYgKGNoaWxkVm5vZGUgaW5zdGFuY2VvZiBWbm9kZSkge1xuICAgICAgICBjaGlsZFZub2RlLmlzU1ZHID0gbmV3UGFyZW50Vm5vZGUuaXNTVkcgfHwgY2hpbGRWbm9kZS5uYW1lID09PSBcInN2Z1wiO1xuICAgICAgfSBlbHNlIGlmIChjaGlsZFZub2RlID09PSBudWxsIHx8IGNoaWxkVm5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBuZXdUcmVlLnNwbGljZShpLS0sIDEpO1xuICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGNoaWxkVm5vZGUpKSB7XG4gICAgICAgIG5ld1RyZWUuc3BsaWNlKGktLSwgMSwgLi4uY2hpbGRWbm9kZSk7XG4gICAgICB9IGVsc2UgaWYgKGNoaWxkVm5vZGUgaW5zdGFuY2VvZiBWbm9kZUNvbXBvbmVudCkge1xuICAgICAgICB2LmN1cnJlbnQuY29tcG9uZW50ID0gY2hpbGRWbm9kZTtcbiAgICAgICAgbmV3VHJlZS5zcGxpY2UoXG4gICAgICAgICAgaS0tLFxuICAgICAgICAgIDEsXG4gICAgICAgICAgLi4uW1xuICAgICAgICAgICAgXCJ2aWV3XCIgaW4gY2hpbGRWbm9kZS5jb21wb25lbnRcbiAgICAgICAgICAgICAgPyBjaGlsZFZub2RlLmNvbXBvbmVudC52aWV3LmNhbGwoY2hpbGRWbm9kZS5jb21wb25lbnQsIGNoaWxkVm5vZGUucHJvcHMsIGNoaWxkVm5vZGUuY2hpbGRyZW4pXG4gICAgICAgICAgICAgIDogKGNoaWxkVm5vZGUuY29tcG9uZW50IGFzIENvbXBvbmVudCkuY2FsbChjaGlsZFZub2RlLmNvbXBvbmVudCwgY2hpbGRWbm9kZS5wcm9wcywgY2hpbGRWbm9kZS5jaGlsZHJlbilcbiAgICAgICAgICBdXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaSA+IDAgJiYgbmV3VHJlZVtpIC0gMV0ubm9kZVZhbHVlKSB7XG4gICAgICAgICAgbmV3VHJlZVtpIC0gMV0ubm9kZVZhbHVlICs9IGNoaWxkVm5vZGU7XG4gICAgICAgICAgbmV3VHJlZS5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZFZub2RlIGluc3RhbmNlb2YgVGV4dFZub2RlID09PSBmYWxzZSkge1xuICAgICAgICAgIG5ld1RyZWVbaV0gPSBuZXcgVGV4dFZub2RlKFN0cmluZyhjaGlsZFZub2RlKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgbmV3VHJlZUxlbmd0aCA9IG5ld1RyZWUubGVuZ3RoO1xuXG4gICAgLy8gaWYgbmV3VHJlZSBpcyBlbXB0eSwgcmVtb3ZlIGl0XG4gICAgaWYgKG5ld1RyZWVMZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvbGRUcmVlTGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IgKGxldCBpID0gb2xkVHJlZUxlbmd0aDsgaS0tOyApIHtcbiAgICAgICAgICBvbGRUcmVlW2ldIGluc3RhbmNlb2YgVm5vZGUgJiYgY2FsbFJlbW92ZShvbGRUcmVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGYXN0IG5vZGUgcmVtb3ZlIGJ5IHNldHRpbmcgdGV4dENvbnRlbnRcbiAgICAgICAgbmV3UGFyZW50Vm5vZGUuZG9tLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICAgIH1cbiAgICAgIC8vIElmIHRoZSB0cmVlIGlzIGtleWVkIGxpc3QgYW5kIGlzIG5vdCBmaXJzdCByZW5kZXJcbiAgICB9IGVsc2UgaWYgKG9sZFRyZWVMZW5ndGggJiYgbmV3VHJlZVswXSBpbnN0YW5jZW9mIFZub2RlICYmIFwia2V5XCIgaW4gbmV3VHJlZVswXS5wcm9wcykge1xuICAgICAgLy8gMS4gTXV0YXRlIHRoZSBvbGQga2V5IGxpc3QgdG8gbWF0Y2ggdGhlIG5ldyBrZXkgbGlzdFxuICAgICAgbGV0IG9sZEtleWVkTGlzdDtcblxuICAgICAgLy8gaWYgdGhlIG9sZFRyZWUgZG9lcyBub3QgaGF2ZSBhIGtleWVkIGxpc3QgZmFzdCByZW1vdmUgYWxsIG5vZGVzXG4gICAgICBpZiAob2xkVHJlZVswXSBpbnN0YW5jZW9mIFZub2RlID09PSBmYWxzZSB8fCBcImtleVwiIGluIG9sZFRyZWVbMF0ucHJvcHMgPT09IGZhbHNlKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBvbGRUcmVlTGVuZ3RoOyBpLS07ICkge1xuICAgICAgICAgIG9sZFRyZWVbaV0gaW5zdGFuY2VvZiBWbm9kZSAmJiBjYWxsUmVtb3ZlKG9sZFRyZWVbaV0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZhc3Qgbm9kZSByZW1vdmUgYnkgc2V0dGluZyB0ZXh0Q29udGVudFxuICAgICAgICBuZXdQYXJlbnRWbm9kZS5kb20udGV4dENvbnRlbnQgPSBcIlwiO1xuICAgICAgICBvbGRLZXllZExpc3QgPSBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9sZEtleWVkTGlzdCA9IG9sZFRyZWUubWFwKCh2bm9kZSkgPT4gdm5vZGUucHJvcHMua2V5KTtcbiAgICAgIH1cblxuICAgICAgLy8gMi4gT2J0YWluIHRoZSBtYXggbGVuZ3RoIG9mIGJvdGggbGlzdHNcbiAgICAgIGxldCBuZXdLZXllZExpc3QgPSBuZXdUcmVlLm1hcCgodm5vZGUpID0+IHZub2RlLnByb3BzLmtleSk7XG4gICAgICBjb25zdCBtYXhMaXN0TGVuZ3RoID0gTWF0aC5tYXgobmV3VHJlZUxlbmd0aCwgb2xkS2V5ZWRMaXN0Lmxlbmd0aCk7XG5cbiAgICAgIC8vIDMuIEN5Y2xlIG92ZXIgYWxsIHRoZSBlbGVtZW50cyBvZiB0aGUgbGlzdCB1bnRpbCB0aGUgbWF4IGxlbmd0aFxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhMaXN0TGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPCBuZXdUcmVlTGVuZ3RoKSB7XG4gICAgICAgICAgbGV0IGNoaWxkVm5vZGUgPSBuZXdUcmVlW2ldO1xuICAgICAgICAgIGxldCBvbGRDaGlsZFZub2RlID0gb2xkS2V5ZWRMaXN0W2ldID09PSBuZXdLZXllZExpc3RbaV0gPyBvbGRUcmVlW2ldIDogb2xkVHJlZVtvbGRLZXllZExpc3QuaW5kZXhPZihjaGlsZFZub2RlLnByb3BzLmtleSldO1xuICAgICAgICAgIGxldCBzaG91bGRQYXRjaCA9IHRydWU7XG5cbiAgICAgICAgICBpZiAob2xkQ2hpbGRWbm9kZSkge1xuICAgICAgICAgICAgY2hpbGRWbm9kZS5kb20gPSBvbGRDaGlsZFZub2RlLmRvbTtcbiAgICAgICAgICAgIG9sZENoaWxkVm5vZGUucHJvY2Vzc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChcInYtb25jZVwiIGluIGNoaWxkVm5vZGUucHJvcHMgfHwgKGNoaWxkVm5vZGUucHJvcHMub25iZWZvcmV1cGRhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmJlZm9yZXVwZGF0ZShjaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKSA9PT0gZmFsc2UpKSB7XG4gICAgICAgICAgICAgIC8vIHNraXAgdGhpcyBwYXRjaFxuICAgICAgICAgICAgICBjaGlsZFZub2RlLmNoaWxkcmVuID0gb2xkQ2hpbGRWbm9kZS5jaGlsZHJlbjtcbiAgICAgICAgICAgICAgc2hvdWxkUGF0Y2ggPSBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlbW92ZVByb3BlcnRpZXMoY2hpbGRWbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBEb21FbGVtZW50IH0sIG9sZENoaWxkVm5vZGUpO1xuICAgICAgICAgICAgICB1cGRhdGVQcm9wZXJ0aWVzKGNoaWxkVm5vZGUgYXMgVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9LCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgICAgICAgaWYgKHYuaXNNb3VudGVkKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRWbm9kZS5wcm9wcy5vbnVwZGF0ZSAmJiBjaGlsZFZub2RlLnByb3BzLm9udXBkYXRlKGNoaWxkVm5vZGUsIG9sZENoaWxkVm5vZGUpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZShjaGlsZFZub2RlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaGlsZFZub2RlLmRvbSA9IGNyZWF0ZUVsZW1lbnQoY2hpbGRWbm9kZS5uYW1lLCBjaGlsZFZub2RlLmlzU1ZHKTtcbiAgICAgICAgICAgIHVwZGF0ZVByb3BlcnRpZXMoY2hpbGRWbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBEb21FbGVtZW50IH0pO1xuICAgICAgICAgICAgY2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZSAmJiBjaGlsZFZub2RlLnByb3BzLm9uY3JlYXRlKGNoaWxkVm5vZGUpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuZXdQYXJlbnRWbm9kZS5kb20uY2hpbGROb2Rlc1tpXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBuZXdQYXJlbnRWbm9kZS5kb20uYXBwZW5kQ2hpbGQoY2hpbGRWbm9kZS5kb20pO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmV3UGFyZW50Vm5vZGUuZG9tLmNoaWxkTm9kZXNbaV0gIT09IGNoaWxkVm5vZGUuZG9tKSB7XG4gICAgICAgICAgICBvbGRUcmVlW2ldIGluc3RhbmNlb2YgVm5vZGUgJiYgIW9sZFRyZWVbaV0ucHJvY2Vzc2VkICYmIG5ld0tleWVkTGlzdC5pbmRleE9mKG9sZFRyZWVbaV0ucHJvcHMua2V5KSA9PT0gLTEgJiYgY2FsbFJlbW92ZShvbGRUcmVlW2ldKTtcbiAgICAgICAgICAgIG5ld1BhcmVudFZub2RlLmRvbS5yZXBsYWNlQ2hpbGQoY2hpbGRWbm9kZS5kb20sIG5ld1BhcmVudFZub2RlLmRvbS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzaG91bGRQYXRjaCAmJiBwYXRjaChjaGlsZFZub2RlIGFzIFZub2RlICYgeyBkb206IERvbUVsZW1lbnQgfSwgb2xkQ2hpbGRWbm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFvbGRUcmVlW2ldLnByb2Nlc3NlZCkge1xuICAgICAgICAgICAgb2xkVHJlZVtpXSBpbnN0YW5jZW9mIFZub2RlICYmIGNhbGxSZW1vdmUob2xkVHJlZVtpXSk7XG4gICAgICAgICAgICBvbGRUcmVlW2ldLmRvbS5wYXJlbnROb2RlICYmIG5ld1BhcmVudFZub2RlLmRvbS5yZW1vdmVDaGlsZChvbGRUcmVlW2ldLmRvbSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmV3VHJlZUxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZFZub2RlID0gbmV3VHJlZVtpXTtcbiAgICAgICAgbGV0IG9sZENoaWxkVm5vZGUgPSBvbGRUcmVlW2ldO1xuXG4gICAgICAgIC8vIGlmIG9sZENoaWxkVm5vZGUgaXMgdW5kZWZpbmVkLCBpdCdzIGEgbmV3IG5vZGUsIGFwcGVuZCBpdFxuICAgICAgICBpZiAob2xkQ2hpbGRWbm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKGNoaWxkVm5vZGUgaW5zdGFuY2VvZiBWbm9kZSkge1xuICAgICAgICAgICAgY2hpbGRWbm9kZS5kb20gPSBjcmVhdGVFbGVtZW50KGNoaWxkVm5vZGUubmFtZSwgY2hpbGRWbm9kZS5pc1NWRyk7XG4gICAgICAgICAgICB1cGRhdGVQcm9wZXJ0aWVzKGNoaWxkVm5vZGUgYXMgVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9KTtcbiAgICAgICAgICAgIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmNyZWF0ZShjaGlsZFZub2RlKTtcbiAgICAgICAgICAgIHBhdGNoKGNoaWxkVm5vZGUgYXMgVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2hpbGRWbm9kZS5kb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjaGlsZFZub2RlLm5vZGVWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5ld1BhcmVudFZub2RlLmRvbS5hcHBlbmRDaGlsZChjaGlsZFZub2RlLmRvbSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgY2hpbGRWbm9kZSBpcyBWbm9kZSwgcmVwbGFjZSBpdCB3aXRoIGl0cyBET00gbm9kZVxuICAgICAgICAgIGlmIChjaGlsZFZub2RlIGluc3RhbmNlb2YgVm5vZGUpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZFZub2RlLm5hbWUgPT09IG9sZENoaWxkVm5vZGUubmFtZSkge1xuICAgICAgICAgICAgICBjaGlsZFZub2RlLmRvbSA9IG9sZENoaWxkVm5vZGUuZG9tO1xuXG4gICAgICAgICAgICAgIGlmIChcInYtb25jZVwiIGluIGNoaWxkVm5vZGUucHJvcHMgfHwgKGNoaWxkVm5vZGUucHJvcHMub25iZWZvcmV1cGRhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbmJlZm9yZXVwZGF0ZShjaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKSA9PT0gZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgLy8gc2tpcCB0aGlzIHBhdGNoXG4gICAgICAgICAgICAgICAgY2hpbGRWbm9kZS5jaGlsZHJlbiA9IG9sZENoaWxkVm5vZGUuY2hpbGRyZW47XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZW1vdmVQcm9wZXJ0aWVzKGNoaWxkVm5vZGUgYXMgVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9LCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgICAgICAgdXBkYXRlUHJvcGVydGllcyhjaGlsZFZub2RlIGFzIFZub2RlICYgeyBkb206IERvbUVsZW1lbnQgfSwgb2xkQ2hpbGRWbm9kZSk7XG4gICAgICAgICAgICAgIGlmICh2LmlzTW91bnRlZCkge1xuICAgICAgICAgICAgICAgIGNoaWxkVm5vZGUucHJvcHMub251cGRhdGUgJiYgY2hpbGRWbm9kZS5wcm9wcy5vbnVwZGF0ZShjaGlsZFZub2RlLCBvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZFZub2RlLnByb3BzLm9uY3JlYXRlICYmIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUoY2hpbGRWbm9kZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcGF0Y2goY2hpbGRWbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBEb21FbGVtZW50IH0sIG9sZENoaWxkVm5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY2hpbGRWbm9kZS5kb20gPSBjcmVhdGVFbGVtZW50KGNoaWxkVm5vZGUubmFtZSwgY2hpbGRWbm9kZS5pc1NWRyk7XG4gICAgICAgICAgICAgIHVwZGF0ZVByb3BlcnRpZXMoY2hpbGRWbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBEb21FbGVtZW50IH0pO1xuICAgICAgICAgICAgICBjaGlsZFZub2RlLnByb3BzLm9uY3JlYXRlICYmIGNoaWxkVm5vZGUucHJvcHMub25jcmVhdGUoY2hpbGRWbm9kZSk7XG4gICAgICAgICAgICAgIG9sZENoaWxkVm5vZGUgaW5zdGFuY2VvZiBWbm9kZSAmJiBjYWxsUmVtb3ZlKG9sZENoaWxkVm5vZGUpO1xuICAgICAgICAgICAgICBuZXdQYXJlbnRWbm9kZS5kb20ucmVwbGFjZUNoaWxkKGNoaWxkVm5vZGUuZG9tLCBvbGRDaGlsZFZub2RlLmRvbSk7XG4gICAgICAgICAgICAgIHBhdGNoKGNoaWxkVm5vZGUgYXMgVm5vZGUgJiB7IGRvbTogRG9tRWxlbWVudCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKG9sZENoaWxkVm5vZGUgaW5zdGFuY2VvZiBWbm9kZSkge1xuICAgICAgICAgICAgICBjaGlsZFZub2RlLmRvbSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNoaWxkVm5vZGUubm9kZVZhbHVlKTtcbiAgICAgICAgICAgICAgY2FsbFJlbW92ZShvbGRDaGlsZFZub2RlKTtcbiAgICAgICAgICAgICAgbmV3UGFyZW50Vm5vZGUuZG9tLnJlcGxhY2VDaGlsZChjaGlsZFZub2RlLmRvbSwgb2xkQ2hpbGRWbm9kZS5kb20gYXMgRG9tRWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjaGlsZFZub2RlLmRvbSA9IG9sZENoaWxkVm5vZGUuZG9tO1xuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG4gICAgICAgICAgICAgIGlmIChjaGlsZFZub2RlLm5vZGVWYWx1ZSAhPSBjaGlsZFZub2RlLmRvbS5ub2RlVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjaGlsZFZub2RlLmRvbS5ub2RlVmFsdWUgPSBjaGlsZFZub2RlLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBGb3IgcmVtYWluaW5nIG9sZCBjaGlsZHJlbjogcmVtb3ZlIGZyb20gRE9NLCBnYXJiYWdlIGNvbGxlY3RcbiAgICAgIGZvciAobGV0IGkgPSBvbGRUcmVlTGVuZ3RoIC0gMTsgaSA+PSBuZXdUcmVlTGVuZ3RoOyAtLWkpIHtcbiAgICAgICAgb2xkVHJlZVtpXSBpbnN0YW5jZW9mIFZub2RlICYmIGNhbGxSZW1vdmUob2xkVHJlZVtpXSk7XG4gICAgICAgIG9sZFRyZWVbaV0uZG9tLnBhcmVudE5vZGUgJiYgbmV3UGFyZW50Vm5vZGUuZG9tLnJlbW92ZUNoaWxkKG9sZFRyZWVbaV0uZG9tKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBuZXdQYXJlbnRWbm9kZS5jaGlsZHJlbiA9IG5ld1RyZWU7XG4gIH1cblxuICBsZXQgbWFpblZub2RlOiBWbm9kZSB8IG51bGwgPSBudWxsO1xuICBsZXQgb2xkTWFpblZub2RlOiBWbm9kZSB8IG51bGwgPSBudWxsO1xuXG4gIHYudW5Nb3VudCA9ICgpID0+IHtcbiAgICBtb3VudGVkQ29tcG9uZW50ID0gZW1wdHlDb21wb25lbnQ7XG4gICAgbGV0IHJlc3VsdCA9IHYudXBkYXRlKCk7XG4gICAgdi5pc01vdW50ZWQgPSBmYWxzZTtcbiAgICBtYWluQ29udGFpbmVyID0gbnVsbDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIHYudXBkYXRlID0gKHByb3BzLCAuLi5jaGlsZHJlbikgPT4ge1xuICAgIGlmIChtYWluVm5vZGUpIHtcbiAgICAgIGNsZWFudXBWbm9kZXMoKTtcbiAgICAgIG9sZE1haW5Wbm9kZSA9IG1haW5Wbm9kZTtcbiAgICAgIG1haW5Wbm9kZSA9IG5ldyBWbm9kZShtYWluVm5vZGUubmFtZSwgbWFpblZub2RlLnByb3BzLCBbdihtb3VudGVkQ29tcG9uZW50LCBwcm9wcywgLi4uY2hpbGRyZW4pXSk7XG4gICAgICBtYWluVm5vZGUuZG9tID0gb2xkTWFpblZub2RlLmRvbTtcbiAgICAgIG1haW5Wbm9kZS5pc1NWRyA9IG9sZE1haW5Wbm9kZS5pc1NWRztcbiAgICAgIHBhdGNoKG1haW5Wbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBOb2RlIH0sIG9sZE1haW5Wbm9kZSBhcyBWbm9kZSAmIHsgZG9tOiBOb2RlIH0pO1xuICAgICAgdi5pc01vdW50ZWQgPSB0cnVlO1xuICAgICAgaWYgKHYuaXNOb2RlKSB7XG4gICAgICAgIHJldHVybiAobWFpblZub2RlLmRvbSBhcyBIVE1MRWxlbWVudCkuaW5uZXJIVE1MO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2Lm1vdW50ID0gKGNvbnRhaW5lciwgY29tcG9uZW50LCBwcm9wcywgLi4uY2hpbGRyZW4pID0+IHtcbiAgICBpZiAodi5pc01vdW50ZWQpIHtcbiAgICAgIHYudW5Nb3VudCgpO1xuICAgIH1cblxuICAgIGlmIChpc05vZGUpIHtcbiAgICAgIG1haW5Db250YWluZXIgPSB0eXBlb2YgY29udGFpbmVyID09PSBcInN0cmluZ1wiID8gY3JlYXRlRWxlbWVudChjb250YWluZXIsIGNvbnRhaW5lciA9PT0gXCJzdmdcIikgOiBjb250YWluZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1haW5Db250YWluZXIgPSB0eXBlb2YgY29udGFpbmVyID09PSBcInN0cmluZ1wiID8gKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoY29udGFpbmVyKVswXSBhcyBEb21FbGVtZW50KSA6IGNvbnRhaW5lcjtcbiAgICB9XG5cbiAgICBpZiAobWFpbkNvbnRhaW5lciAhPT0gbnVsbCkge1xuICAgICAgbWFpblZub2RlID0gZG9tVG9Wbm9kZShtYWluQ29udGFpbmVyKTtcbiAgICAgIG1haW5Wbm9kZS5pc1NWRyA9IG1haW5Wbm9kZS5uYW1lID09PSBcInN2Z1wiO1xuICAgICAgb2xkTWFpblZub2RlID0gbWFpblZub2RlO1xuICAgICAgbW91bnRlZENvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gdi51cGRhdGUocHJvcHMsIC4uLmNoaWxkcmVuKTtcbiAgfTtcblxuICBsZXQgZGlyZWN0aXZlczogUmVjb3JkPHN0cmluZywgRGlyZWN0aXZlPiA9IHt9O1xuXG4gIHYuZGlyZWN0aXZlID0gKG5hbWU6IHN0cmluZywgZGlyZWN0aXZlOiBEaXJlY3RpdmUpID0+IHtcbiAgICBsZXQgZnVsbE5hbWUgPSBgdi0ke25hbWV9YDtcbiAgICBpZiAocmVzZXJ2ZWRXb3Jkcy5pbmRleE9mKGZ1bGxOYW1lKSA9PT0gLTEpIHtcbiAgICAgIHJlc2VydmVkV29yZHMucHVzaChmdWxsTmFtZSk7XG4gICAgICBkaXJlY3RpdmVzW2Z1bGxOYW1lXSA9IGRpcmVjdGl2ZTtcbiAgICB9XG4gIH07XG5cbiAgbGV0IGhpZGVEaXJlY3RpdmUgPSAodGVzdDogYm9vbGVhbikgPT4gKGJvb2w6IGJvb2xlYW4sIHZub2RlOiBWbm9kZSwgb2xkbm9kZT86IFZub2RlIHwgVGV4dFZub2RlKSA9PiB7XG4gICAgbGV0IHZhbHVlID0gdGVzdCA/IGJvb2wgOiAhYm9vbDtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIGxldCBuZXdkb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlwiKTtcbiAgICAgIGlmIChvbGRub2RlICYmIG9sZG5vZGUuZG9tICYmIG9sZG5vZGUuZG9tLnBhcmVudE5vZGUpIHtcbiAgICAgICAgb2xkbm9kZSBpbnN0YW5jZW9mIFZub2RlICYmIGNhbGxSZW1vdmUob2xkbm9kZSk7XG4gICAgICAgIG9sZG5vZGUuZG9tLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld2RvbSwgb2xkbm9kZS5kb20pO1xuICAgICAgfVxuICAgICAgdm5vZGUubmFtZSA9IFwiI3RleHRcIjtcbiAgICAgIHZub2RlLmNoaWxkcmVuID0gW107XG4gICAgICB2bm9kZS5wcm9wcyA9IHt9O1xuICAgICAgdm5vZGUuZG9tID0gbmV3ZG9tIGFzIHVua25vd24gYXMgRG9tRWxlbWVudDtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgdi5kaXJlY3RpdmUoXCJpZlwiLCBoaWRlRGlyZWN0aXZlKGZhbHNlKSk7XG4gIHYuZGlyZWN0aXZlKFwidW5sZXNzXCIsIGhpZGVEaXJlY3RpdmUodHJ1ZSkpO1xuICB2LmRpcmVjdGl2ZShcImZvclwiLCAoc2V0OiB1bmtub3duW10sIHZub2RlOiBWbm9kZSkgPT4ge1xuICAgIHZub2RlLmNoaWxkcmVuID0gc2V0Lm1hcCh2bm9kZS5jaGlsZHJlblswXSBhcyAodmFsdWU6IHVua25vd24pID0+IEZ1bmN0aW9uKTtcbiAgfSk7XG4gIHYuZGlyZWN0aXZlKFwic2hvd1wiLCAoYm9vbDogYm9vbGVhbiwgdm5vZGU6IFZub2RlKSA9PiB7XG4gICAgKHZub2RlLmRvbSBhcyB7IHN0eWxlOiB7IGRpc3BsYXk6IHN0cmluZyB9IH0pLnN0eWxlLmRpc3BsYXkgPSBib29sID8gXCJcIiA6IFwibm9uZVwiO1xuICB9KTtcbiAgdi5kaXJlY3RpdmUoXCJjbGFzc1wiLCAoY2xhc3NlczogeyBbeDogc3RyaW5nXTogYm9vbGVhbiB9LCB2bm9kZTogVm5vZGUpID0+IHtcbiAgICBmb3IgKGxldCBuYW1lIGluIGNsYXNzZXMpIHtcbiAgICAgICh2bm9kZS5kb20gYXMgRG9tRWxlbWVudCkuY2xhc3NMaXN0LnRvZ2dsZShuYW1lLCBjbGFzc2VzW25hbWVdKTtcbiAgICB9XG4gIH0pO1xuICB2LmRpcmVjdGl2ZShcImh0bWxcIiwgKGh0bWw6IHN0cmluZywgdm5vZGU6IFZub2RlKSA9PiB7XG4gICAgdm5vZGUuY2hpbGRyZW4gPSBbdHJ1c3QoaHRtbCldO1xuICB9KTtcblxuICB2Lm5ld0luc3RhbmNlID0gdmFseXJpYW47XG5cbiAgcmV0dXJuIHY7XG59XG5cbigoaXNOb2RlID8gZ2xvYmFsIDogd2luZG93KSBhcyB1bmtub3duIGFzIHsgdjogVmFseXJpYW4gfSkudiA9IHZhbHlyaWFuKCk7XG4iXX0= \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts index 7e5a1b9..3680816 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,564 +1,722 @@ -/* eslint-disable complexity */ -/* eslint-disable sonarjs/cognitive-complexity */ /* eslint-disable no-use-before-define */ -/* eslint-disable no-unused-vars */ +/* eslint-disable sonarjs/cognitive-complexity */ +/*** Vnode ***/ + +import { + Children, + Current, + Directive, + Directives, + DomElement, + IVnode, + MountedValyrianApp, + Plugin, + Props, + ReservedProps, + Valyrian, + ValyrianApp, + ValyrianComponent, + VnodeComponent, + VnodeWithDom +} from "./interfaces"; + +/*** Constants ***/ +const ComponentString = "__component__"; +const TextString = "#text"; +const isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); +const ValyrianSymbol = Symbol("Valyrian"); +const Und = undefined; + +/*** Vnode ***/ + +const Vnode = function Vnode(this: IVnode, tag: string, props: Props, children: Children) { + this.props = props; + this.children = children; + this.tag = tag; +} as unknown as IVnode; + +function isVnode(object?: unknown | IVnode): object is IVnode { + return object instanceof Vnode; +} -type VnodeOrUnknown = VnodeComponent | Vnode | TextVnode | any; +function isComponent(component?: unknown | ValyrianComponent): component is ValyrianComponent { + return typeof component === "function" || (typeof component === "object" && component !== null && "view" in component); +} -type DomAttribute = { nodeName: string; nodeValue: string }; +function isVnodeComponent(vnode?: unknown | VnodeComponent): vnode is VnodeComponent { + return vnode instanceof Vnode && vnode.tag === ComponentString; +} -type DomElement = (HTMLElement | SVGElement) & Record; +/*** Util ***/ -type Props = { - key?: string | number; - data?: string; - oncreate?: { (vnode: Vnode): never }; - onupdate?: { (vnode: Vnode, oldVnode: Vnode | TextVnode): never }; - onremove?: { (oldVnode: Vnode): never }; - onbeforeupdate?: { (vnode: Vnode, oldVnode: Vnode | TextVnode): undefined | boolean }; -} & Record; +function createDomElement(tag: string, isSVG: boolean = false) { + return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); +} -type Component = (props?: Record | null, children?: VnodeOrUnknown) => VnodeOrUnknown | VnodeOrUnknown[]; +function domToVnode(dom: DomElement): VnodeWithDom { + let vnode = v( + dom.tagName.toLowerCase(), + {}, + ...Array.from(dom.childNodes) + .filter((child) => (child as DomElement).nodeType === 1 || (child as DomElement).nodeType === 3) + .map((child) => { + if ((child as DomElement).nodeType === 1) { + return domToVnode(child as DomElement); + } -type ValyrianComponent = - | Component - | (Record & { - view: Component; - }); + let text = new Vnode(TextString, {}, []); + text.nodeValue = String((child as DomElement).nodeValue); + text.dom = child as DomElement; + return text; + }) + ); + [].forEach.call(dom.attributes, (prop: Attr) => (vnode.props[prop.nodeName] = prop.nodeValue)); + vnode.dom = dom; + return vnode as VnodeWithDom; +} -type Current = { parentVnode?: Vnode; oldParentVnode?: Vnode; component?: VnodeComponent }; +const trust = (htmlString: string): Children => { + let div = createDomElement("div"); + div.innerHTML = htmlString.trim(); -interface Plugin { - (v: Valyrian, options?: Record): never; -} + return [].map.call(div.childNodes, (item) => domToVnode(item)) as Children; +}; -interface Directive { - (value: any, vnode: Vnode, oldVnode?: Vnode | TextVnode): void | boolean; -} +const reservedProps: ReservedProps = { + key: true, + state: true, + oncreate: true, + onupdate: true, + onremove: true, + shouldupdate: true, + "v-once": true, + + // Built in directives + "v-if": true, + "v-unless": true, + "v-for": true, + "v-show": true, + "v-class": true, + "v-html": true +}; + +/*** Mount ***/ -interface ValyrianEventHandler { - (a: Event, dom: DomElement): void; +const current: Current = {}; + +function onCleanup(callback: Function) { + if (current.app?.onCleanup.indexOf(callback) === -1) { + current.app?.onCleanup.push(callback); + } } -interface Vnode { - name: string; - props: Props; - children: VnodeOrUnknown[]; - dom?: DomElement; - onCleanup?: FunctionConstructor[]; - isSVG?: boolean; - processed?: boolean; +function onUnmount(callback: Function) { + if (current.app?.onUnmount.indexOf(callback) === -1) { + current.app?.onUnmount.push(callback); + } } -class Vnode implements Vnode { - name: string; - props: Props; - children: VnodeOrUnknown[]; - dom?: DomElement; - onCleanup?: FunctionConstructor[]; - isSVG?: boolean; - processed?: boolean; - - constructor(name: string, props: Props, children: VnodeOrUnknown) { - this.props = props; - this.children = children; - this.name = name; +function onMount(callback: Function) { + if (current.app?.onMount.indexOf(callback) === -1) { + current.app?.onMount.push(callback); } } -interface TextVnode { - dom?: Text; - nodeValue: string; +function onUpdate(callback: Function) { + if (current.app?.onUpdate.indexOf(callback) === -1) { + current.app?.onUpdate.push(callback); + } } -class TextVnode implements TextVnode { - dom?: Text; - nodeValue: string; +/* + * Mounts a component to the DOM + mount('#app', () =>
Hello world
); // App is a Functional Component + mount('#app', { view: () =>
Hello world
}); // App is a POJO component with a view method + mount('#app', classInstance); // App is a class instance with a view method + mount('#app',
Hello world
); // App is a Vnode component (Vnode with tag __component__) +*/ + +function mount(container: DomElement | string, component: ValyrianComponent | IVnode): void | string { + let appContainer = null; + + if (isNodeJs) { + appContainer = typeof container === "string" ? createDomElement(container === "svg" ? "svg" : "div", container === "svg") : container; + } else { + appContainer = typeof container === "string" ? document.querySelectorAll(container)[0] : container; + } - constructor(nodeValue: string) { - this.nodeValue = nodeValue; + if (!appContainer) { + throw new Error("Container not found"); } -} -interface VnodeComponent { - component: ValyrianComponent; - props: Props; - children: VnodeOrUnknown[]; -} + let vnodeComponent: VnodeComponent | IVnode; -class VnodeComponent implements VnodeComponent { - component: ValyrianComponent; - props: Props; - children: VnodeOrUnknown[]; + if (isVnodeComponent(component)) { + vnodeComponent = component; + } else if (isComponent(component)) { + vnodeComponent = v(component, {}); + } else { + throw new Error("Component must be a Valyrian Component or a Vnode component"); + } - constructor(component: ValyrianComponent, props: Props, children: VnodeOrUnknown[]) { - this.props = props; - this.children = children; - this.component = component; + if (component[ValyrianSymbol]) { + unmount(component); + } else { + component[ValyrianSymbol] = { + isMounted: false, + eventListenerNames: {}, + onCleanup: [], + onMount: [], + onUpdate: [], + onUnmount: [] + }; + function eventListener(e: Event) { + let dom = e.target as DomElement & Record; + let name = `v-on${e.type}`; + while (dom) { + if (dom[name]) { + dom[name](e, dom); + if (!e.defaultPrevented) { + update(component); + } + return; + } + dom = dom.parentNode as DomElement; + } + } + component[ValyrianSymbol].eventListener = eventListener; } + + component[ValyrianSymbol].component = vnodeComponent; + component[ValyrianSymbol].container = appContainer; + component[ValyrianSymbol].mainVnode = domToVnode(appContainer); + + // update + return update(component); } -interface Valyrian { - (tagOrComponent: string | ValyrianComponent, props?: Props | null, children?: VnodeOrUnknown): Vnode | VnodeComponent; - fragment: (props: Props, children: VnodeOrUnknown[]) => VnodeOrUnknown[]; - isMounted: boolean; - isNode: boolean; - reservedWords: string[]; - current: Current; - trust: (htmlString: string) => Vnode[]; - usePlugin: (plugin: Plugin, options: Record) => void; - onCleanup: (callback: typeof Function) => void; - updateProperty: (name: string, newVnode: Vnode & { dom: DomElement }, oldNode: Vnode & { dom: DomElement }) => void; - update: (props?: Props | null, ...children: VnodeOrUnknown) => string | void; - mount: (container: string | DomElement, component: ValyrianComponent, props?: Props | null, ...children: VnodeOrUnknown[]) => string | void; - unMount: () => string | boolean | void; - directive: (directive: string, handler: Directive) => void; - newInstance: () => Valyrian; - [x: string]: any; +function callCleanup(valyrianApp: ValyrianApp) { + for (let i = 0; i < valyrianApp.onCleanup.length; i++) { + valyrianApp.onCleanup[i](); + } + valyrianApp.onCleanup = []; } -let isNode = typeof window === "undefined" || typeof global !== "undefined"; +function callUnmount(valyrianApp: ValyrianApp) { + for (let i = 0; i < valyrianApp.onUnmount.length; i++) { + valyrianApp.onUnmount[i](); + } + valyrianApp.onUnmount = []; +} -// Create Node element -function createElement(tagName: string, isSVG: boolean = false): DomElement { - return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName); +function callMount(valyrianApp: ValyrianApp) { + for (let i = 0; i < valyrianApp.onMount.length; i++) { + valyrianApp.onMount[i](); + } + valyrianApp.onMount = []; } -// Transforms a DOM node to a VNode -function domToVnode(dom: DomElement): Vnode { - let props: Props = {}; - [].forEach.call(dom.attributes, (prop: Attr) => (props[prop.nodeName] = prop.nodeValue)); +function callUpdate(valyrianApp: ValyrianApp) { + for (let i = 0; i < valyrianApp.onUpdate.length; i++) { + valyrianApp.onUpdate[i](); + } + valyrianApp.onUpdate = []; +} - let vnode: Vnode = new Vnode(dom.nodeName.toLowerCase(), props, []); - vnode.dom = dom; +function update(component?: ValyrianComponent | IVnode): void | string { + if (component && component[ValyrianSymbol]) { + let valyrianApp = component[ValyrianSymbol]; + current.app = valyrianApp; + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + let oldVnode: VnodeWithDom | null = valyrianApp.mainVnode as VnodeWithDom; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, [valyrianApp.component]) as VnodeWithDom; + valyrianApp.mainVnode.dom = oldVnode.dom; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; + if (valyrianApp.isMounted === false) { + valyrianApp.onMount.length && callMount(valyrianApp); + valyrianApp.isMounted = true; + } else { + valyrianApp.onUpdate.length && callUpdate(valyrianApp); + } - for (let i = 0, l = dom.childNodes.length; i < l; i++) { - if (dom.childNodes[i].nodeType === 1) { - vnode.children.push(domToVnode(dom.childNodes[i] as DomElement)); - } else if (dom.childNodes[i].nodeType === 3) { - let textVnode = new TextVnode(dom.childNodes[i].nodeValue || ""); - textVnode.dom = dom.childNodes[i] as unknown as Text; - vnode.children.push(textVnode); + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; } } - return vnode; } -const trust = (htmlString: string) => { - let div = createElement("div"); - div.innerHTML = htmlString.trim(); - - return [].map.call(div.childNodes, (item) => domToVnode(item)) as Vnode[]; -}; +function unmount(component?: ValyrianComponent | IVnode): void | string { + if (!component || !component[ValyrianSymbol]) { + return; + } -// eslint-disable-next-line max-lines-per-function -function valyrian(): Valyrian { - const v: Valyrian = (tagOrComponent, props, ...children) => { - if (typeof tagOrComponent === "string") { - return new Vnode(tagOrComponent, props || {}, children); - } else { - return new VnodeComponent(tagOrComponent, props || {}, children); - } - }; + let valyrianApp = component[ValyrianSymbol] as MountedValyrianApp; - v.fragment = (props: Props, vnodes: VnodeOrUnknown[]) => { - return vnodes; - }; + if (valyrianApp.isMounted) { + valyrianApp.onCleanup.length && callCleanup(valyrianApp); + valyrianApp.onUnmount.length && callUnmount(valyrianApp); + let oldVnode: VnodeWithDom | null = valyrianApp.mainVnode as VnodeWithDom; + valyrianApp.mainVnode = new Vnode(valyrianApp.mainVnode.tag, valyrianApp.mainVnode.props, []) as VnodeWithDom; + valyrianApp.mainVnode.dom = oldVnode.dom; + valyrianApp.mainVnode.isSVG = oldVnode.isSVG; + patch(valyrianApp.mainVnode, oldVnode, valyrianApp); + oldVnode = null; - v.isMounted = false; - v.isNode = isNode; - const reservedWords = ["key", "data", "v-once", "oncreate", "onupdate", "onremove", "onbeforeupdate"]; - v.reservedWords = reservedWords; - v.trust = trust; + if (isNodeJs) { + return valyrianApp.mainVnode.dom.innerHTML; + } - const current: Current = { - parentVnode: undefined, - oldParentVnode: undefined, - component: undefined - }; - v.current = current; + (valyrianApp as any) = null; + Reflect.deleteProperty(component, ValyrianSymbol); + } +} - const plugins = new Map(); +let emptyVnode = new Vnode("__empty__", {}, []); - v.usePlugin = (plugin: Plugin, options: Record = {}) => !plugins.has(plugin) && plugins.set(plugin, true) && plugin(v as Valyrian, options); +function onremove(vnode: IVnode) { + for (let i = 0; i < vnode.children.length; i++) { + vnode.children[i].tag !== TextString && onremove(vnode.children[i]); + } - let vnodesToCleanup: Vnode[] = []; + vnode.props.onremove && vnode.props.onremove(vnode); +} - v.onCleanup = (callback: FunctionConstructor) => { - let parentVnode = v.current.parentVnode as Vnode; - if (!parentVnode.onCleanup) { - parentVnode.onCleanup = [] as FunctionConstructor[]; +function sharedSetAttribute(prop: string, value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean { + // It is a reserved prop + if (reservedProps[prop]) { + // If it is a directive name call the directive + if (directives[prop]) { + return directives[prop](vnode.props[prop], vnode, oldVnode); } - parentVnode.onCleanup.push(callback); - - if (vnodesToCleanup.indexOf(parentVnode) === -1) { - vnodesToCleanup.push(parentVnode); - } - }; + return; + } - let cleanupVnodes = () => { - for (let l = vnodesToCleanup.length; l--; ) { - for (let callback of vnodesToCleanup[l].onCleanup as FunctionConstructor[]) { - callback(); - } + // It is not a reserved prop so we add it to the dom + if (typeof value === "function") { + let valyrianApp = current.app as MountedValyrianApp; + if (prop in valyrianApp.eventListenerNames === false) { + valyrianApp.eventListenerNames[prop] = true; + valyrianApp.container.addEventListener(prop.slice(2), valyrianApp.eventListener); } - vnodesToCleanup = []; - }; + vnode.dom[`v-${prop}`] = value; + return; + } - let mainContainer: DomElement | null = null; - let emptyComponent: ValyrianComponent = () => ""; - let mountedComponent: ValyrianComponent = emptyComponent; - - const attachedListeners: string[] = []; - function eventListener(e: Event) { - let dom = e.target as DomElement; - let name = `v-on${e.type}`; - while (dom) { - if (dom[name]) { - (dom[name] as ValyrianEventHandler)(e, dom); - if (!e.defaultPrevented) { - v.update(); - } - return; - } - dom = dom.parentNode as DomElement; + if (prop in vnode.dom && vnode.isSVG === false) { + // eslint-disable-next-line eqeqeq + if (vnode.dom[prop] != value) { + vnode.dom[prop] = value; } + return; } - function updateProperty(prop: string, newVnode: Vnode & { dom: DomElement }, oldVnode?: Vnode): void | boolean { - if (reservedWords.indexOf(prop) !== -1) { - if (prop in directives) { - return directives[prop](newVnode.props[prop], newVnode, oldVnode); - } - } else if (typeof newVnode.props[prop] === "function") { - if (attachedListeners.indexOf(prop) === -1) { - (mainContainer as DomElement).addEventListener(prop.slice(2), eventListener); - attachedListeners.push(prop); - } - newVnode.dom[`v-${prop}`] = newVnode.props[prop]; - } else if (prop in newVnode.dom && !newVnode.isSVG) { - // eslint-disable-next-line eqeqeq - if (newVnode.dom[prop] != newVnode.props[prop]) { - newVnode.dom[prop] = newVnode.props[prop]; - } - } else if (oldVnode === undefined || newVnode.props[prop] !== oldVnode.props[prop]) { - if (newVnode.props[prop] === false) { - newVnode.dom.removeAttribute(prop); - } else { - newVnode.dom.setAttribute(prop, newVnode.props[prop]); - } + // Use set attribute + if (!oldVnode || oldVnode.props[prop] !== value) { + if (value === false) { + vnode.dom.removeAttribute(prop); + } else { + vnode.dom.setAttribute(prop, value); } } - v.updateProperty = updateProperty; +} - // Update a Vnode.dom HTMLElement with new Vnode props that are different from old Vnode props - function updateProperties(newVnode: Vnode & { dom: DomElement }, oldVnode?: Vnode): void { - for (let prop in newVnode.props) { - if (updateProperty(prop, newVnode, oldVnode) === false) { - return; - } +function setAttribute(name: string, value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) { + vnode.props[name] = value; + + sharedSetAttribute(name, value, vnode, oldVnode); +} + +function setAttributes(vnode: VnodeWithDom, oldVnode?: VnodeWithDom) { + for (let prop in vnode.props) { + if (sharedSetAttribute(prop, vnode.props[prop], vnode, oldVnode) === false) { + return; } } - function removeProperties(newVnode: Vnode & { dom: DomElement }, oldVnode: Vnode) { - for (let name in oldVnode.props) { - if (name in newVnode.props === false && typeof oldVnode.props[name] !== "function" && reservedWords.indexOf(name) === -1) { - if (name in newVnode.dom) { - newVnode.dom[name] = null; + if (oldVnode) { + for (let prop in oldVnode.props) { + if (prop in vnode.props === false && typeof oldVnode.props[prop] !== "function" && prop in reservedProps === false) { + if (prop in oldVnode.dom && vnode.isSVG === false) { + oldVnode.dom[prop] = null; } else { - newVnode.dom.removeAttribute(name); + oldVnode.dom.removeAttribute(prop); } } } } +} - const callRemove = (vnode: Vnode) => { - for (let i = 0, l = vnode.children.length; i < l; i++) { - vnode.children[i] instanceof Vnode && callRemove(vnode.children[i]); +// eslint-disable-next-line complexity +function patch(newVnode: VnodeWithDom, oldVnode: VnodeWithDom | IVnode = emptyVnode, valyrianApp: MountedValyrianApp) { + current.vnode = newVnode; + current.oldVnode = oldVnode === emptyVnode ? Und : (oldVnode as VnodeWithDom); + let newTree = newVnode.children; + let oldTree = oldVnode.children; + + for (let i = 0; i < newTree.length; i++) { + let childVnode = newTree[i]; + if (childVnode instanceof Vnode) { + if (childVnode.tag !== TextString) { + if (childVnode.tag === ComponentString) { + let component = childVnode.component as ValyrianComponent; + current.component = component; + let result = ("view" in component ? component.view : component).call(component, childVnode.props, ...childVnode.children); + + newTree.splice(i--, 1, result); + continue; + } + childVnode.isSVG = newVnode.isSVG || childVnode.tag === "svg"; + } + } else if (Array.isArray(childVnode)) { + newTree.splice(i--, 1, ...childVnode); + } else if (childVnode === null || childVnode === Und) { + newTree.splice(i--, 1); + } else { + newTree[i] = new Vnode(TextString, {}, []); + newTree[i].nodeValue = childVnode; } + } - vnode.props.onremove && vnode.props.onremove(vnode); - }; - // Patch a DOM node with a new VNode tree - function patch(newParentVnode: Vnode & { dom: DomElement }, oldParentVnode?: Vnode & { dom: DomElement }): void { - let oldTree = oldParentVnode?.children || []; - let newTree = newParentVnode.children; - let oldTreeLength = oldTree.length; + let oldTreeLength = oldTree.length; + let newTreeLength = newTree.length; - current.parentVnode = newParentVnode; - current.oldParentVnode = oldParentVnode; + // If new tree is empty, remove all old nodes + if (newTreeLength === 0) { + for (let i = 0; i < oldTreeLength; i++) { + oldTree[i].tag !== TextString && onremove(oldTree[i]); + } - // Flat newTree - for (let i = 0; i < newTree.length; i++) { - let childVnode = newTree[i]; + newVnode.dom.textContent = ""; + return; + } - if (childVnode instanceof Vnode) { - childVnode.isSVG = newParentVnode.isSVG || childVnode.name === "svg"; - } else if (childVnode === null || childVnode === undefined) { - newTree.splice(i--, 1); - } else if (Array.isArray(childVnode)) { - newTree.splice(i--, 1, ...childVnode); - } else if (childVnode instanceof VnodeComponent) { - v.current.component = childVnode; - newTree.splice( - i--, - 1, - ...[ - "view" in childVnode.component - ? childVnode.component.view.call(childVnode.component, childVnode.props, childVnode.children) - : (childVnode.component as Component).call(childVnode.component, childVnode.props, childVnode.children) - ] - ); - } else { - if (i > 0 && newTree[i - 1].nodeValue) { - newTree[i - 1].nodeValue += childVnode; - newTree.splice(i--, 1); - } else if (childVnode instanceof TextVnode === false) { - newTree[i] = new TextVnode(String(childVnode)); - } - } + // If the tree is keyed list and is not first render and old tree is keyed list too + if (oldTreeLength && "key" in newTree[0].props && "key" in oldTree[0].props) { + let oldKeyedList: { [key: string]: number } = {}; + for (let i = 0; i < oldTreeLength; i++) { + oldKeyedList[oldTree[i].props.key] = i; } - let newTreeLength = newTree.length; + let newKeyedList: { [key: string]: number } = {}; + for (let i = 0; i < newTreeLength; i++) { + newKeyedList[newTree[i].props.key] = i; + } - // if newTree is empty, remove it - if (newTreeLength === 0) { - if (oldTreeLength > 0) { - for (let i = oldTreeLength; i--; ) { - oldTree[i] instanceof Vnode && callRemove(oldTree[i]); - } - // Fast node remove by setting textContent - newParentVnode.dom.textContent = ""; - } - // If the tree is keyed list and is not first render - } else if (oldTreeLength && newTree[0] instanceof Vnode && "key" in newTree[0].props) { - // 1. Mutate the old key list to match the new key list - let oldKeyedList; - - // if the oldTree does not have a keyed list fast remove all nodes - if (oldTree[0] instanceof Vnode === false || "key" in oldTree[0].props === false) { - for (let i = oldTreeLength; i--; ) { - oldTree[i] instanceof Vnode && callRemove(oldTree[i]); + for (let i = 0; i < newTreeLength; i++) { + let childVnode = newTree[i]; + let oldChildVnode = oldTree[oldKeyedList[childVnode.props.key]]; + let shouldPatch = true; + + if (oldChildVnode) { + childVnode.dom = oldChildVnode.dom; + if ("v-once" in childVnode.props || (childVnode.props.shouldupdate && childVnode.props.shouldupdate(childVnode, oldChildVnode) === false)) { + // skip this patch + childVnode.children = oldChildVnode.children; + shouldPatch = false; + } else { + setAttributes(childVnode, oldChildVnode); + if (valyrianApp.isMounted) { + childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); + } else { + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); + } } - // Fast node remove by setting textContent - newParentVnode.dom.textContent = ""; - oldKeyedList = []; } else { - oldKeyedList = oldTree.map((vnode) => vnode.props.key); + childVnode.dom = createDomElement(childVnode.tag, childVnode.isSVG); + setAttributes(childVnode); + childVnode.props.oncreate && childVnode.props.oncreate(childVnode); } - // 2. Obtain the max length of both lists - let newKeyedList = newTree.map((vnode) => vnode.props.key); - const maxListLength = Math.max(newTreeLength, oldKeyedList.length); - - // 3. Cycle over all the elements of the list until the max length - for (let i = 0; i < maxListLength; i++) { - if (i < newTreeLength) { - let childVnode = newTree[i]; - let oldChildVnode = oldKeyedList[i] === newKeyedList[i] ? oldTree[i] : oldTree[oldKeyedList.indexOf(childVnode.props.key)]; - let shouldPatch = true; - - if (oldChildVnode) { - childVnode.dom = oldChildVnode.dom; - oldChildVnode.processed = true; - if ("v-once" in childVnode.props || (childVnode.props.onbeforeupdate && childVnode.props.onbeforeupdate(childVnode, oldChildVnode) === false)) { - // skip this patch - childVnode.children = oldChildVnode.children; - shouldPatch = false; - } else { - removeProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - updateProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - if (v.isMounted) { - childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); - } else { - childVnode.props.oncreate && childVnode.props.oncreate(childVnode); - } - } - } else { - childVnode.dom = createElement(childVnode.name, childVnode.isSVG); - updateProperties(childVnode as Vnode & { dom: DomElement }); - childVnode.props.oncreate && childVnode.props.oncreate(childVnode); - } + if (newVnode.dom.childNodes[i] === Und) { + newVnode.dom.appendChild(childVnode.dom); + } else if (newVnode.dom.childNodes[i] !== childVnode.dom) { + oldTree[i] && newKeyedList[oldTree[i].props.key] === Und && onremove(oldTree[i]); + newVnode.dom.replaceChild(childVnode.dom, newVnode.dom.childNodes[i]); + } - if (newParentVnode.dom.childNodes[i] === undefined) { - newParentVnode.dom.appendChild(childVnode.dom); - } else if (newParentVnode.dom.childNodes[i] !== childVnode.dom) { - oldTree[i] instanceof Vnode && !oldTree[i].processed && newKeyedList.indexOf(oldTree[i].props.key) === -1 && callRemove(oldTree[i]); - newParentVnode.dom.replaceChild(childVnode.dom, newParentVnode.dom.childNodes[i]); - } + shouldPatch && patch(childVnode, oldChildVnode, valyrianApp); + } - shouldPatch && patch(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - } else { - if (!oldTree[i].processed) { - oldTree[i] instanceof Vnode && callRemove(oldTree[i]); - oldTree[i].dom.parentNode && newParentVnode.dom.removeChild(oldTree[i].dom); - } - } - } - } else { - for (let i = 0; i < newTreeLength; i++) { - let childVnode = newTree[i]; + // For the rest of the children, we should remove them + for (let i = newTreeLength; i < oldTreeLength; i++) { + if (newKeyedList[oldTree[i].props.key] === Und) { let oldChildVnode = oldTree[i]; + onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } + } - // if oldChildVnode is undefined, it's a new node, append it - if (oldChildVnode === undefined) { - if (childVnode instanceof Vnode) { - childVnode.dom = createElement(childVnode.name, childVnode.isSVG); - updateProperties(childVnode as Vnode & { dom: DomElement }); - childVnode.props.oncreate && childVnode.props.oncreate(childVnode); - patch(childVnode as Vnode & { dom: DomElement }); - } else { - childVnode.dom = document.createTextNode(childVnode.nodeValue); - } - newParentVnode.dom.appendChild(childVnode.dom); - } else { - // if childVnode is Vnode, replace it with its DOM node - if (childVnode instanceof Vnode) { - if (childVnode.name === oldChildVnode.name) { - childVnode.dom = oldChildVnode.dom; - - if ("v-once" in childVnode.props || (childVnode.props.onbeforeupdate && childVnode.props.onbeforeupdate(childVnode, oldChildVnode) === false)) { - // skip this patch - childVnode.children = oldChildVnode.children; - continue; - } + return; + } - removeProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - updateProperties(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - if (v.isMounted) { - childVnode.props.onupdate && childVnode.props.onupdate(childVnode, oldChildVnode); - } else { - childVnode.props.oncreate && childVnode.props.oncreate(childVnode); - } - patch(childVnode as Vnode & { dom: DomElement }, oldChildVnode); - } else { - childVnode.dom = createElement(childVnode.name, childVnode.isSVG); - updateProperties(childVnode as Vnode & { dom: DomElement }); - childVnode.props.oncreate && childVnode.props.oncreate(childVnode); - oldChildVnode instanceof Vnode && callRemove(oldChildVnode); - newParentVnode.dom.replaceChild(childVnode.dom, oldChildVnode.dom); - patch(childVnode as Vnode & { dom: DomElement }); - } - } else { - if (oldChildVnode instanceof Vnode) { - childVnode.dom = document.createTextNode(childVnode.nodeValue); - callRemove(oldChildVnode); - newParentVnode.dom.replaceChild(childVnode.dom, oldChildVnode.dom as DomElement); - } else { - childVnode.dom = oldChildVnode.dom; - // eslint-disable-next-line eqeqeq - if (childVnode.nodeValue != childVnode.dom.nodeValue) { - childVnode.dom.nodeValue = childVnode.nodeValue; - } - } + // If new tree and old tree have more than one child, we should update the dom + for (let i = 0; i < newTreeLength; i++) { + let newChildVnode = newTree[i]; + + // Old child exists + if (i < oldTreeLength) { + let oldChildVnode = oldTree[i]; + // New child is a text node + if (newChildVnode.tag === TextString) { + // Old child is a text node + if (oldChildVnode.tag === TextString) { + newChildVnode.dom = oldChildVnode.dom; + // eslint-disable-next-line eqeqeq + if (newChildVnode.dom.nodeValue != newChildVnode.nodeValue) { + newChildVnode.dom.nodeValue = newChildVnode.nodeValue as string; } + continue; } - } - // For remaining old children: remove from DOM, garbage collect - for (let i = oldTreeLength - 1; i >= newTreeLength; --i) { - oldTree[i] instanceof Vnode && callRemove(oldTree[i]); - oldTree[i].dom.parentNode && newParentVnode.dom.removeChild(oldTree[i].dom); - } - } + // Old child is a normal node + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue as string) as unknown as DomElement; + onremove(oldChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); - newParentVnode.children = newTree; - } + continue; + } - let mainVnode: Vnode | null = null; - let oldMainVnode: Vnode | null = null; + // New child is a normal node + // Old child is the same type as new child + if (oldChildVnode.tag === newChildVnode.tag) { + newChildVnode.dom = oldChildVnode.dom; + // If we have a v-once directive or a shouldupdate method that returns false, we skip the update + if (newChildVnode.props["v-once"] || (newChildVnode.props.shouldupdate && newChildVnode.props.shouldupdate(newChildVnode, oldChildVnode) === false)) { + newChildVnode.children = oldChildVnode.children; + continue; + } - v.unMount = () => { - mountedComponent = emptyComponent; - let result = v.update(); - v.isMounted = false; - mainContainer = null; - return result; - }; + // We update the dom element + setAttributes(newChildVnode, oldChildVnode); + if (valyrianApp.isMounted) { + newChildVnode.props.onupdate && newChildVnode.props.onupdate(newChildVnode, oldChildVnode); + } else { + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + } - v.update = (props, ...children) => { - if (mainVnode) { - cleanupVnodes(); - oldMainVnode = mainVnode; - mainVnode = new Vnode(mainVnode.name, mainVnode.props, [v(mountedComponent, props, ...children)]); - mainVnode.dom = oldMainVnode.dom; - mainVnode.isSVG = oldMainVnode.isSVG; - patch(mainVnode as Vnode & { dom: Node }, oldMainVnode as Vnode & { dom: Node }); - v.isMounted = true; - if (v.isNode) { - return (mainVnode.dom as HTMLElement).innerHTML; + patch(newChildVnode, oldChildVnode, valyrianApp); + continue; } - } - }; - v.mount = (container, component, props, ...children) => { - if (v.isMounted) { - v.unMount(); + // Old child is of a different type than new child + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + newVnode.dom.replaceChild(newChildVnode.dom, oldChildVnode.dom); + patch(newChildVnode, emptyVnode, valyrianApp); + continue; } - if (isNode) { - mainContainer = typeof container === "string" ? createElement(container, container === "svg") : container; - } else { - mainContainer = typeof container === "string" ? (document.querySelectorAll(container)[0] as DomElement) : container; + // Old child does not exists + // New child is a text node + if (newChildVnode.tag === TextString) { + newChildVnode.dom = document.createTextNode(newChildVnode.nodeValue as string) as unknown as DomElement; + newVnode.dom.appendChild(newChildVnode.dom); + continue; } - if (mainContainer !== null) { - mainVnode = domToVnode(mainContainer); - mainVnode.isSVG = mainVnode.name === "svg"; - oldMainVnode = mainVnode; - mountedComponent = component; - } + // New child is a normal node + newChildVnode.dom = createDomElement(newChildVnode.tag, newChildVnode.isSVG); + setAttributes(newChildVnode); + newVnode.dom.appendChild(newChildVnode.dom); + newChildVnode.props.oncreate && newChildVnode.props.oncreate(newChildVnode); + patch(newChildVnode, emptyVnode, valyrianApp); + } - return v.update(props, ...children); - }; + // For the rest of the children, we should remove them + for (let i = newTreeLength; i < oldTreeLength; i++) { + let oldChildVnode = oldTree[i]; + oldChildVnode.tag !== TextString && onremove(oldChildVnode); + oldChildVnode.dom.parentNode && oldChildVnode.dom.parentNode.removeChild(oldChildVnode.dom); + } +} - let directives: Record = {}; +/*** Directives ***/ - v.directive = (name: string, directive: Directive) => { - let fullName = `v-${name}`; - if (reservedWords.indexOf(fullName) === -1) { - reservedWords.push(fullName); - directives[fullName] = directive; - } - }; +function directive(name: string, directive: Directive) { + let fullName = `v-${name}`; + directives[fullName] = directive; + reservedProps[fullName] = true; +} - let hideDirective = (test: boolean) => (bool: boolean, vnode: Vnode, oldnode?: Vnode | TextVnode) => { +function hideDirective(test: boolean): Directive { + return (bool: boolean, vnode: IVnode, oldVnode?: IVnode) => { let value = test ? bool : !bool; if (value) { let newdom = document.createTextNode(""); - if (oldnode && oldnode.dom && oldnode.dom.parentNode) { - oldnode instanceof Vnode && callRemove(oldnode); - oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); + if (oldVnode && oldVnode.dom && oldVnode.dom.parentNode) { + oldVnode.tag !== TextString && onremove(oldVnode); + oldVnode.dom.parentNode.replaceChild(newdom, oldVnode.dom); } - vnode.name = "#text"; + vnode.tag = TextString; vnode.children = []; vnode.props = {}; vnode.dom = newdom as unknown as DomElement; return false; } }; +} - v.directive("if", hideDirective(false)); - v.directive("unless", hideDirective(true)); - v.directive("for", (set: unknown[], vnode: Vnode) => { - vnode.children = set.map(vnode.children[0] as (value: unknown) => Function); - }); - v.directive("show", (bool: boolean, vnode: Vnode) => { - (vnode.dom as { style: { display: string } }).style.display = bool ? "" : "none"; - }); - v.directive("class", (classes: { [x: string]: boolean }, vnode: Vnode) => { +const directives: Directives = { + "v-if": hideDirective(false), + "v-unless": hideDirective(true), + "v-for": (set: unknown[], vnode: VnodeWithDom) => { + vnode.children = set.map(vnode.children[0]); + }, + "v-show": (bool: boolean, vnode: VnodeWithDom) => { + (vnode.dom as unknown as { style: { display: string } }).style.display = bool ? "" : "none"; + }, + "v-class": (classes: { [x: string]: boolean }, vnode: VnodeWithDom) => { for (let name in classes) { (vnode.dom as DomElement).classList.toggle(name, classes[name]); } - }); - v.directive("html", (html: string, vnode: Vnode) => { + }, + "v-html": (html: string, vnode: VnodeWithDom) => { vnode.children = [trust(html)]; - }); + }, + "v-model": ([model, property, event]: any[], vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => { + let value; + let handler; + if (vnode.name === "input") { + event = event || "oninput"; + switch (vnode.props.type) { + case "checkbox": { + if (Array.isArray(model[property])) { + handler = (e: Event) => { + let val = (e.target as DomElement & Record).value; + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + }; + value = model[property].indexOf(vnode.dom.value) !== -1; + } else if ("value" in vnode.props) { + handler = () => { + if (model[property] === vnode.props.value) { + model[property] = null; + } else { + model[property] = vnode.props.value; + } + }; + value = model[property] === vnode.props.value; + } else { + handler = () => (model[property] = !model[property]); + value = model[property]; + } + setAttribute("checked", value, vnode, oldVnode); + break; + } + case "radio": { + setAttribute("checked", model[property] === vnode.dom.value, vnode, oldVnode); + break; + } + default: { + setAttribute("value", model[property], vnode, oldVnode); + } + } + } else if (vnode.name === "select") { + event = event || "onclick"; + if (vnode.props.multiple) { + handler = (e: Event & Record) => { + let val = (e.target as DomElement & Record).value; + if (e.ctrlKey) { + let idx = model[property].indexOf(val); + if (idx === -1) { + model[property].push(val); + } else { + model[property].splice(idx, 1); + } + } else { + model[property].splice(0, model[property].length); + model[property].push(val); + } + }; + vnode.children.forEach((child: IVnode) => { + if (child.tag === "option") { + let value = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = model[property].indexOf(value) !== -1; + } + }); + } else { + vnode.children.forEach((child: IVnode) => { + if (child.tag === "option") { + let value = "value" in child.props ? child.props.value : child.children.join("").trim(); + child.props.selected = value === model[property]; + } + }); + } + } else if (vnode.name === "textarea") { + event = event || "oninput"; + vnode.children = [model[property]]; + } + + if (!vnode.props[event]) { + if (!handler) { + handler = (e: Event) => (model[property] = (e.target as DomElement & Record).value); + } + setAttribute(event, handler, vnode, oldVnode); + } + } +}; + +/*** Plugins ***/ +const plugins = new Map(); - v.newInstance = valyrian; +function use(plugin: Plugin, options?: Record): void | any { + if (plugins.has(plugin)) { + return plugins.get(plugin); + } - return v; + let result = plugin(v, options); + plugins.set(plugin, result); + return result; } -((isNode ? global : window) as unknown as { v: Valyrian }).v = valyrian(); +/*** Hyperscript ***/ + +export const v: Valyrian = function v(tagOrComponent: string | ValyrianComponent, props: Props, ...children: Children): IVnode | VnodeComponent { + if (typeof tagOrComponent === "string") { + return new Vnode(tagOrComponent, props || {}, children); + } + + const vnode = new Vnode("__component__", props || {}, children); + vnode.component = tagOrComponent; + return vnode as VnodeComponent; +}; + +v.fragment = (props: Props, ...children: Children): Children => { + return children; +}; + +/*** V properties and methods ***/ +// This is intended to make the properties and methods available for plugins +v.current = current; + +v.directives = directives; + +v.reservedProps = reservedProps; + +v.isVnode = isVnode; +v.isComponent = isComponent; +v.isVnodeComponent = isVnodeComponent; + +v.isNodeJs = isNodeJs; +v.trust = trust; + +v.onCleanup = onCleanup; +v.onUnmount = onUnmount; +v.onMount = onMount; +v.onUpdate = onUpdate; + +v.mount = mount; +v.unmount = unmount; +v.update = update; + +v.setAttribute = setAttribute; +v.directive = directive; +v.use = use; diff --git a/lib/interfaces.ts b/lib/interfaces.ts new file mode 100644 index 0000000..a629d58 --- /dev/null +++ b/lib/interfaces.ts @@ -0,0 +1,140 @@ +/* eslint-disable no-use-before-define */ +/* eslint-disable no-unused-vars */ +/*** Interfaces ***/ + +export interface DomElement extends Element { + [key: string]: any; +} + +export interface Props { + key?: string | number; + data?: string; + oncreate?: { (vnode: IVnode): never }; + onupdate?: { (vnode: IVnode, oldVnode: IVnode): never }; + onremove?: { (oldVnode: IVnode): never }; + shouldupdate?: { (vnode: IVnode, oldVnode: IVnode): undefined | boolean }; + [key: string | number | symbol]: any; +} + +export interface Children extends Array {} + +export interface IVnode { + new (tag: string, props: Props, children: Children): IVnode; + tag: string; + props: Props; + children: Children; + dom?: DomElement; + isSVG?: boolean; + processed?: boolean; + component?: Component | POJOComponent; + nodeValue?: string; + [key: string | number | symbol]: any; +} + +export interface Component { + (props?: Record | null, children?: Children): IVnode | Children; + [key: string | number | symbol]: any; +} + +export interface POJOComponent { + view: Component; + [key: string | number | symbol]: any; +} + +export type ValyrianComponent = Component | POJOComponent; + +export interface VnodeComponent extends IVnode { + tag: "__component__"; + component: ValyrianComponent; +} + +export interface VnodeWithDom extends IVnode { + dom: DomElement; +} + +export interface Directive { + (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void; +} + +export interface ValyrianApp { + isMounted: boolean; + eventListenerNames: Record; + onCleanup: Function[]; + onUnmount: Function[]; + onMount: Function[]; + onUpdate: Function[]; + + eventListener?: EventListener; + mainVnode?: VnodeWithDom; + container?: DomElement; + + [key: string | number | symbol]: any; +} + +export interface MountedValyrianApp extends ValyrianApp { + eventListener: EventListener; + mainVnode: VnodeWithDom; + container: DomElement; +} + +export interface Current { + app?: ValyrianApp; + component?: ValyrianComponent; + vnode?: VnodeWithDom; + oldVnode?: VnodeWithDom; +} + +export interface Directives { + [key: string]: Directive; +} + +export interface ReservedProps { + [key: string]: true; +} + +export interface Plugin { + (valyrian: Valyrian, options?: Record): void | any; +} + +export interface Valyrian { + (tagOrComponent: string | ValyrianComponent, props: Props, ...children: Children): IVnode | VnodeComponent; + fragment: (props: Props, ...children: Children) => Children; + current: Current; + directives: Directives; + reservedProps: ReservedProps; + + isVnode: (object?: unknown | IVnode) => object is IVnode; + isComponent: (component?: unknown | ValyrianComponent) => component is ValyrianComponent; + isVnodeComponent: (vnode?: unknown | VnodeComponent) => vnode is VnodeComponent; + + isNodeJs: boolean; + trust: (htmlString: string) => Children; + + onCleanup: (fn: Function) => void; + onUnmount: (fn: Function) => void; + onMount: (fn: Function) => void; + onUpdate: (fn: Function) => void; + + mount: (container: DomElement | string, component: ValyrianComponent | IVnode) => void | string; + update: (component: ValyrianComponent | IVnode) => void | string; + unmount: (component: ValyrianComponent | IVnode) => void | string; + + setAttribute: (name: string, value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void; + directive: (name: string, directive: Directive) => void; + use: (plugin: Plugin, options?: Record) => void | any; + + [key: string | number | symbol]: any; +} + +declare global { + namespace JSX { + type Element = IVnode; + interface IntrinsicElements { + [elemName: string]: any; + } + } +} + +interface HTMLAttributes { + [key: string]: any; +} diff --git a/package.json b/package.json index 10150d2..95ffc00 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,11 @@ "version": "5.0.17", "description": "Lightweight steel to forge PWAs. (Minimal Frontend Framework with server side rendering and other capabilities)", "source": "lib/index.ts", - "main": "dist/valyrian.min.js", - "module": "dist/valyrian.min.js", - "unpkg": "dist/valyrian.min.js", - "browser": "dist/valyrian.min.js", - "types": "dist/types/lib/index.d.ts", + "main": "dist/index.cjs", + "module": "dist/index.js", + "unpkg": "dist/index.cjs", + "browser": "dist/index.min.js", + "types": "dist/@types/lib/index.d.ts", "repository": "git@github.com:Masquerade-Circus/valyrian.js.git", "author": "Masquerade ", "license": "Apache-2.0", @@ -39,7 +39,7 @@ }, "scripts": { "dev:source": "cross-env NODE_ENV=development nodemon -e js,ts,json,css -w ./test -w ./lib -w ./plugins source.js", - "dev:test": "cross-env NODE_ENV=development nodemon -e js,ts,json,css -w ./test -w ./lib -w ./plugins --exec 'mocha --bail --timeout 10000 --slow 0 --require ./register \"test/**/*_test.js\"'", + "dev:test": "cross-env NODE_ENV=development nodemon -e js,ts,json,css,tsx -w ./test -w ./lib -w ./plugins --exec 'mocha --bail --timeout 10000 --slow 0 --require ./register'", "dev:test:nyc": "cross-env NODE_ENV=development nodemon -w ./test -w ./lib -w ./plugins --exec 'nyc --reporter=text --reporter=lcov mocha --timeout 10000 --slow 0 --require ./register \"test/**/*_test.js\"'", "build": "yarn build:source && yarn remark", "build:source": "cross-env NODE_ENV=production node source.js", @@ -49,46 +49,44 @@ "commit": "git add . && git-cz", "release": "release-it --verbose", "release-test": "release-it --dry-run --verbose", - "bench": " nodemon -e js,ts,json,css -w ./bench -w ./lib -w ./plugins --exec 'buffalo-test --require ./register'" + "bench": "nodemon -e js,ts,json,css,tsx -w ./bench -w ./lib -w ./plugins --exec 'buffalo-test --require ./register'" }, "dependencies": { - "clean-css": "^5.2.2", - "esbuild": "^0.14.5", + "clean-css": "^5.2.4", + "esbuild": "^0.14.22", "favicons": "^6.2.2", "form-data": "^4.0.0", - "node-fetch": "2.6.1", + "node-fetch": "2.6.7", "parse5": "^6.0.1", - "pirates": "^4.0.4", + "pirates": "^4.0.5", "purgecss": "4.1.3", "terser": "^5.10.0", - "ts-node": "^10.4.0", + "ts-node": "^10.5.0", "tsc-prog": "^2.2.1", "tslib": "^2.3.1", - "typescript": "^4.5.4" + "typescript": "^4.5.5" }, "devDependencies": { - "@release-it/conventional-changelog": "^3.3.0", - "@types/node": "^17.0.0", - "@typescript-eslint/eslint-plugin": "^5.7.0", - "@typescript-eslint/parser": "^5.7.0", + "@release-it/conventional-changelog": "^4.1.0", + "@types/node": "^17.0.18", + "@typescript-eslint/eslint-plugin": "^5.12.0", + "@typescript-eslint/parser": "^5.12.0", "buffalo-test": "^2.0.0", "compression": "^1.7.4", "cross-env": "^7.0.3", "cz-conventional-changelog": "3.3.0", "dayjs": "^1.10.7", - "eslint": "^8.4.1", + "eslint": "^8.9.0", "eslint-plugin-sonarjs": "^0.11.0", - "expect": "^27.4.2", - "faker": "^5.5.3", - "fastify": "^3.25.0", + "expect": "^27.5.1", + "fastify": "^3.27.1", "gzip-size": "^7.0.0", - "mocha": "^9.1.3", - "node-dev": "^7.1.0", + "mocha": "^9.2.0", + "nodemon": "^2.0.15", "nyc": "^15.1.0", - "release-it": "^14.11.8", + "release-it": "^14.12.4", "remark-cli": "^10.0.1", - "remark-toc": "^8.0.1", - "yargs": "^17.3.0" + "remark-toc": "^8.0.1" }, "nyc": { "exclude": [ @@ -188,6 +186,8 @@ } }, "resolutions": { - "minimist": "^1.2.5" + "minimist": "^1.2.5", + "jpeg-js": "^0.4.0", + "ansi-regex": "^5.0.1" } -} +} \ No newline at end of file diff --git a/plugins/hooks.js b/plugins/hooks.js index d19dac1..8de6998 100644 --- a/plugins/hooks.js +++ b/plugins/hooks.js @@ -1,91 +1,161 @@ -let plugin = function (v) { - let UND; +let v = { + current: {} +}; - v.createHook = function ({ name, init, update, response }) { - name = `use${name.charAt(0).toUpperCase()}${name.slice(1).toLowerCase()}`; - if (!v[name]) { - v[name] = (...args) => { - let { component, parentVnode, oldParentVnode } = v.current; +function createHook({ create, update, remove, returnValue }) { + return (...args) => { + let { component, vnode, oldVnode, app } = v.current; - if (parentVnode.components === UND) { - parentVnode.components = []; - } + // Init the components array for the current vnode + if (vnode.components === undefined) { + vnode.components = []; + app.onUnmount.push(() => { + Reflect.deleteProperty(vnode, "components"); + }); + } - if (parentVnode.components.indexOf(component) === -1) { - parentVnode.components.push(component); - } + // Add the component to the components array if it's not already there + if (vnode.components.indexOf(component) === -1) { + vnode.components.push(component); + } - let hook; - let oldComponentNode = oldParentVnode && oldParentVnode.components && oldParentVnode.components[parentVnode.components.length - 1]; - let oldMethod = oldComponentNode && ("view" in oldComponentNode.component ? oldComponentNode.component.view : oldComponentNode.component); - let currentMethod = "view" in component.component ? component.component.view : component.component; + // Init the component hooks array + if (component.hooks === undefined) { + component.hooks = []; + app.onUnmount.push(() => { + Reflect.deleteProperty(component, "hooks"); + }); + } + let hook; - if (component.hooks === UND) { - component.hooks = []; - } - let hookIndex = component.hooks.length; + if (!oldVnode || !oldVnode.components || oldVnode.components[vnode.components.length - 1] !== component) { + hook = create(...args); + component.hooks.push(hook); - if (oldMethod === currentMethod && "hooks" in oldComponentNode && oldComponentNode.hooks[hookIndex] !== UND) { - component.hooks = oldComponentNode.hooks; - hook = oldComponentNode.hooks[hookIndex]; - if (update) { - update(hook, ...args); - } - } else { - hook = init(...args); - component.hooks.push(hook); - } + if (remove) { + // Add the hook to the onRemove array + app.onUnmount.push(() => remove(hook)); + } + } else { + hook = component.hooks[component.hooks.length - 1]; + if (update) { + update(hook, ...args); + } + } - if (response) { - return response(hook); - } - }; + if (returnValue) { + return returnValue(hook); } + + return hook; }; +} - v.createHook({ - name: "state", - init: (value) => { - let state = value; - let setState = (value) => (state = value); +const useState = createHook({ + create: (value) => { + let state = value; + let setState = (value) => (state = value); - let stateObj = Object.create(null); - stateObj.toJSON = stateObj.toString = stateObj.valueOf = () => (typeof state === "function" ? state() : state); + let stateObj = Object.create(null); + stateObj.toJSON = stateObj.toString = stateObj.valueOf = () => (typeof state === "function" ? state() : state); - return [stateObj, setState]; - }, - response: (hook) => hook - }); + return [stateObj, setState]; + } +}); + +// Effect hook +const useEffect = createHook({ + create: (effect, changes) => { + let hook = { effect, prev: [] }; + // on unmount + if (changes === null) { + hook.onRemove = effect; + return hook; + } - // Effect hook - function callHook(hook, changes) { - let { prev } = hook; - if (!changes) { + // on create + hook.prev = changes; + hook.onCleanup = hook.effect(); + return hook; + }, + update: (hook, effect, changes) => { + // on update + if (typeof changes === "undefined") { + hook.prev = changes; + if (typeof hook.onCleanup === "function") { + hook.onCleanup(); + } hook.onCleanup = hook.effect(); - } else if (changes.length > 0) { + return; + } + + // on update if there are changes + if (Array.isArray(changes)) { for (let i = 0, l = changes.length; i < l; i++) { - if (changes[i] !== prev[i]) { + if (changes[i] !== hook.prev[i]) { hook.prev = changes; + if (typeof hook.onCleanup === "function") { + hook.onCleanup(); + } hook.onCleanup = hook.effect(); - break; + return; } } } - + }, + remove: (hook) => { if (typeof hook.onCleanup === "function") { - v.onCleanup(hook.onCleanup); + hook.onCleanup(); + } + if (typeof hook.onRemove === "function") { + hook.onRemove(); } } - v.createHook({ - name: "effect", - init: (effect, changes) => { - let hook = { effect, prev: changes }; - callHook(hook); - return hook; - }, - update: (hook, effect, changes) => callHook(hook, changes) - }); -}; +}); + +const useRef = createHook({ + create: (initialValue) => { + v.directive("ref", (ref, vnode) => { + ref.current = vnode.dom; + }); + return { current: initialValue }; + } +}); + +const useCallback = createHook({ + create: (callback) => { + return callback; + } +}); + +const useMemo = createHook({ + create: (callback, changes) => { + return { callback, changes, value: callback() }; + }, + update: (hook, callback, changes) => { + for (let i = 0, l = changes.length; i < l; i++) { + if (changes[i] !== hook.changes[i]) { + hook.changes = changes; + hook.value = callback(); + return; + } + } + }, + returnValue: (hook) => { + return hook.value; + } +}); + +function plugin(vInstance) { + v = vInstance; +} + +plugin.createHook = createHook; +plugin.useState = useState; +plugin.useEffect = useEffect; +plugin.useRef = useRef; +plugin.useCallback = useCallback; +plugin.useMemo = useMemo; plugin.default = plugin; module.exports = plugin; diff --git a/plugins/node.js b/plugins/node.js index fdbd06d..46e6e6b 100644 --- a/plugins/node.js +++ b/plugins/node.js @@ -1,7 +1,6 @@ /* eslint-disable sonarjs/cognitive-complexity */ let fs = require("fs"); let path = require("path"); -require("ts-node/register"); let fetch = require("node-fetch"); let FormData = require("form-data"); @@ -14,10 +13,6 @@ let CleanCSS = require("clean-css"); const tsc = require("tsc-prog"); -global.fetch = fetch; -global.FormData = FormData; -global.document = treeAdapter.createDocument(); - let errorHandler = (resolve, reject) => (err) => { if (err) { return reject(err); @@ -26,176 +21,91 @@ let errorHandler = (resolve, reject) => (err) => { resolve(); }; -function fileMethodFactory() { - let prop = []; - return function (file, options = {}) { - if (!file) { - return prop; - } +async function inline(file, options = {}) { + if (typeof file === "string") { + let ext = file.split(".").pop(); + if (/(js|cjs|jsx|mjs|ts|tsx)/.test(ext)) { + if (/(ts|tsx)/.test(ext) && !options.noValidate) { + let declarationDir = options.declarationDir; + let emitDeclaration = !!declarationDir; + + let tscProgOptions = { + basePath: process.cwd(), // always required, used for relative paths + configFilePath: "tsconfig.json", // config to inherit from (optional) + files: [file], + include: ["**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx", "**/*.mjs"], + exclude: ["test*/**/*", "**/*.test.ts", "**/*.spec.ts", "dist/**"], + pretty: true, + copyOtherToOutDir: false, + clean: emitDeclaration ? [declarationDir] : [], + ...(options.tsc || {}), + compilerOptions: { + rootDir: "./", + outDir: "dist", + noEmitOnError: true, + noEmit: !emitDeclaration, + declaration: emitDeclaration, + declarationDir, + emitDeclarationOnly: emitDeclaration, + allowJs: true, + esModuleInterop: true, + inlineSourceMap: true, + resolveJsonModule: true, + removeComments: true, + ...(options.tsc || {}).compilerOptions + }, + jsxFactory: "v", + jsxFragment: "v.fragment" + }; - let asyncMethod = async () => { - let contents = ""; - if (typeof file === "string") { - let ext = file.split(".").pop(); - if (/(js|jsx|mjs|ts|tsx)/.test(ext)) { - if (/(ts|tsx)/.test(ext) && !options.noValidate) { - let declarationDir = options.declarationDir; - let emitDeclaration = !!declarationDir; - - let tscProgOptions = { - basePath: process.cwd(), // always required, used for relative paths - configFilePath: "tsconfig.json", // config to inherit from (optional) - files: [file], - include: ["**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx", "**/*.mjs"], - exclude: ["test*/**/*", "**/*.test.ts", "**/*.spec.ts", "dist/**"], - pretty: true, - copyOtherToOutDir: false, - clean: emitDeclaration ? [declarationDir] : [], - ...(options.tsc || {}), - compilerOptions: { - rootDir: "./", - outDir: "dist", - noEmitOnError: true, - noEmit: !emitDeclaration, - declaration: emitDeclaration, - declarationDir, - emitDeclarationOnly: emitDeclaration, - allowJs: true, - esModuleInterop: true, - inlineSourceMap: true, - resolveJsonModule: true, - removeComments: true, - ...(options.tsc || {}).compilerOptions - }, - jsxFactory: "v", - jsxFragment: "v.fragment" - }; - - tsc.build(tscProgOptions); - } + // eslint-disable-next-line no-console + console.log("tsc", tscProgOptions); - let result = esbuild.buildSync({ - entryPoints: [file], - bundle: true, - sourcemap: "external", - write: false, - minify: options.compact, - outdir: "out", - target: "esnext", - jsxFactory: "v", - jsxFragment: "v.fragment", - loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" }, - ...(options.esbuild || {}) - }); - - if (options.compact) { - let result2 = await terser.minify(result.outputFiles[1].text, { - sourceMap: { - content: result.outputFiles[0].text.toString() - }, - compress: { - booleans_as_integers: false - }, - output: { - wrap_func_args: false - }, - ecma: 2020, - ...(options.terser || {}) - }); - - let mapBase64 = Buffer.from(result2.map.toString()).toString("base64"); - let suffix = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`; - contents = { raw: result2.code, map: suffix, file }; - } else { - let mapBase64 = Buffer.from(result.outputFiles[0].text.toString()).toString("base64"); - let suffix = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`; - contents = { raw: result.outputFiles[1].text, map: suffix, file }; - } - } else if (/(css|scss|styl)/.test(ext)) { - let result = new CleanCSS({ - sourceMap: true, - level: { - 1: { - roundingPrecision: "all=3" - }, - 2: { - restructureRules: true // controls rule restructuring; defaults to false - } - } - }).minify([file]); - - contents = { raw: result.styles, map: null, file }; - } else { - contents = { raw: fs.readFileSync(file, "utf8"), map: null, file }; - } - } else if (typeof file === "object" && "raw" in file) { - contents = { map: null, ...file }; + tsc.build(tscProgOptions); } - prop.push(contents); - return prop; - }; - - return asyncMethod(); - }; -} - -async function inline(...args) { - for (let item of args) { - let ext = item.split(".").pop(); - if (!inline[ext]) { - inline[ext] = fileMethodFactory(); - } - await inline[ext](item); - } -} - -inline.extensions = (...extensions) => { - for (let ext of extensions) { - if (!inline[ext]) { - inline[ext] = fileMethodFactory(); - } - } -}; - -inline.css = fileMethodFactory(); -inline.js = fileMethodFactory(); - -inline.uncss = (function () { - let prop = ""; - return function (renderedHtml, options = {}) { - if (!renderedHtml) { - return prop; - } - - let asyncMethod = async () => { - let html = await Promise.all(renderedHtml); - - let contents = html.map((item) => { - return { - raw: item, - extension: "html" - }; - }); - - let purgecss = new PurgeCSS(); - let css = inline - .css() - .map((item) => item.raw) - .join(""); - - let output = await purgecss.purge({ - fontFace: true, - keyframes: true, - variables: true, - defaultExtractor: (content) => content.match(/[A-Za-z0-9-_/:@]*[A-Za-z0-9-_/:@/]+/g) || [], - ...options, - content: contents, - css: [{ raw: css }] - }); - - prop = new CleanCSS({ - sourceMap: false, + let esbuildOptions = { + entryPoints: [file], + bundle: "bundle" in options ? options.bundle : true, + sourcemap: "external", + write: false, + minify: options.compact, + outdir: "out", + target: "esnext", + jsxFactory: "v", + jsxFragment: "v.fragment", + loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" }, + ...(options.esbuild || {}) + }; + + let result = esbuild.buildSync(esbuildOptions); + + if (options.compact) { + let result2 = await terser.minify(result.outputFiles[1].text, { + sourceMap: { + content: result.outputFiles[0].text.toString() + }, + compress: { + booleans_as_integers: false + }, + output: { + wrap_func_args: false + }, + ecma: 2020, + ...(options.terser || {}) + }); + + let mapBase64 = Buffer.from(result2.map.toString()).toString("base64"); + let suffix = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`; + return { raw: result2.code, map: suffix, file }; + } else { + let mapBase64 = Buffer.from(result.outputFiles[0].text.toString()).toString("base64"); + let suffix = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`; + return { raw: result.outputFiles[1].text, map: suffix, file }; + } + } else if (/(css|scss|styl)/.test(ext)) { + let result = new CleanCSS({ + sourceMap: true, level: { 1: { roundingPrecision: "all=3" @@ -203,15 +113,54 @@ inline.uncss = (function () { 2: { restructureRules: true // controls rule restructuring; defaults to false } - } - }).minify(output[0].css).styles; + }, + ...(options.cleanCss || {}) + }).minify([file]); - return prop; + return { raw: result.styles, map: null, file }; + } else { + return { raw: fs.readFileSync(file, "utf8"), map: null, file }; + } + } else if (typeof file === "object" && "raw" in file) { + return { map: null, ...file }; + } +} + +inline.uncss = async function (renderedHtml, css, options = {}) { + let html = await Promise.all(renderedHtml); + + let contents = html.map((item) => { + return { + raw: item, + extension: "html" }; + }); - return asyncMethod(); - }; -})(); + let purgecss = new PurgeCSS(); + + let output = await purgecss.purge({ + fontFace: true, + keyframes: true, + variables: true, + defaultExtractor: (content) => content.match(/[A-Za-z0-9-_/:@]*[A-Za-z0-9-_/:@/]+/g) || [], + ...options, + content: contents, + css: [{ raw: css }] + }); + + return new CleanCSS({ + sourceMap: false, + level: { + 1: { + roundingPrecision: "all=3" + }, + 2: { + restructureRules: true // controls rule restructuring; defaults to false + } + }, + ...(options.cleanCss || {}) + }).minify(output[0].css).styles; +}; function sw(file, options = {}) { let swfiletemplate = path.resolve(__dirname, "./node.sw.tpl.js"); @@ -341,25 +290,36 @@ icons.options = { } }; -let plugin = function (v) { - v.inline = inline; - v.sw = sw; - v.icons = icons; - v.htmlToDom = treeAdapter.htmlToDom; - v.domToHtml = treeAdapter.domToHtml; - v.domToHyperscript = treeAdapter.domToHyperscript; - v.htmlToHyperscript = treeAdapter.htmlToHyperscript; - v.hyperscriptToHtml = (...args) => v.mount("div", () => args); -}; +let mount = () => {}; +let unmount = () => {}; +let isInUse = false; + +function plugin(v) { + mount = v.mount; + unmount = v.unmount; + isInUse = true; + global.fetch = fetch; + global.FormData = FormData; + global.document = treeAdapter.createDocument(); +} plugin.inline = inline; plugin.sw = sw; plugin.icons = icons; -plugin.htmlToDom = treeAdapter.htmlToDom; +plugin.htmlTDom = treeAdapter.htmlToDom; plugin.domToHtml = treeAdapter.domToHtml; plugin.domToHyperscript = treeAdapter.domToHyperscript; plugin.htmlToHyperscript = treeAdapter.htmlToHyperscript; -plugin.hyperscriptToHtml = (...args) => v.mount("div", () => args); +plugin.render = (...args) => { + if (!isInUse) { + throw new Error("This plugin is not in use. Please invoke `v.use(nodePlugin)`"); + } + + let Component = () => args; + let result = mount("div", Component); + unmount(Component); + return result; +}; plugin.default = plugin; module.exports = plugin; diff --git a/plugins/request.js b/plugins/request.js index e0acdbf..0a7e87d 100644 --- a/plugins/request.js +++ b/plugins/request.js @@ -1,3 +1,5 @@ +const isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); + function serialize(obj, prefix) { return Object.keys(obj) .map((p) => { @@ -7,159 +9,154 @@ function serialize(obj, prefix) { .join("&"); } -let plugin = function(v) { - function parseUrl(url, options = {}) { - let u = /^https?/gi.test(url) ? url : options.urls.base + url; - - let parts = u.split("?"); - u = parts[0] - .trim() - .replace(/^\/\//, "/") - .replace(/\/$/, "") - .trim(); +function parseUrl(url, options = {}) { + let u = /^https?/gi.test(url) ? url : options.urls.base + url; - if (parts[1]) { - u += `?${parts[1]}`; - } + let parts = u.split("?"); + u = parts[0].trim().replace(/^\/\//, "/").replace(/\/$/, "").trim(); - if (v.isNode && typeof options.urls.node === "string") { - options.urls.node = options.urls.node; + if (parts[1]) { + u += `?${parts[1]}`; + } - if (typeof options.urls.api === "string") { - options.urls.api = options.urls.api.replace(/\/$/gi, "").trim(); - u = u.replace(options.urls.api, options.urls.node); - } + if (isNodeJs && typeof options.urls.node === "string") { + options.urls.node = options.urls.node; - if (!/^https?/gi.test(u)) { - u = options.urls.node + u; - } + if (typeof options.urls.api === "string") { + options.urls.api = options.urls.api.replace(/\/$/gi, "").trim(); + u = u.replace(options.urls.api, options.urls.node); } - return u; + if (!/^https?/gi.test(u)) { + u = options.urls.node + u; + } } - function Request(baseUrl = "", options = {}) { - let url = baseUrl.replace(/\/$/gi, "").trim(); - options.urls = options.urls || {}; - let opts = { - methods: ["get", "post", "put", "patch", "delete"], - ...options, - urls: { - node: options.urls.node || null, - api: options.urls.api || null, - base: options.urls.base ? options.urls.base + url : url - } + return u; +} + +// eslint-disable-next-line sonarjs/cognitive-complexity +function Request(baseUrl = "", options = {}) { + let url = baseUrl.replace(/\/$/gi, "").trim(); + options.urls = options.urls || {}; + let opts = { + methods: ["get", "post", "put", "patch", "delete"], + ...options, + urls: { + node: options.urls.node || null, + api: options.urls.api || null, + base: options.urls.base ? options.urls.base + url : url + } + }; + + async function request(method, url, data, options = {}) { + let innerOptions = { + method: method.toLowerCase(), + headers: {}, + resolveWithFullResponse: false, + ...opts, + ...options }; - async function request(method, url, data, options = {}) { - let innerOptions = { - method: method.toLowerCase(), - headers: {}, - resolveWithFullResponse: false, - ...opts, - ...options - }; - - if (!innerOptions.headers.Accept) { - innerOptions.headers.Accept = "application/json"; - } + if (!innerOptions.headers.Accept) { + innerOptions.headers.Accept = "application/json"; + } - let acceptType = innerOptions.headers.Accept; - let contentType = innerOptions.headers["Content-Type"] || innerOptions.headers["content-type"] || ""; + let acceptType = innerOptions.headers.Accept; + let contentType = innerOptions.headers["Content-Type"] || innerOptions.headers["content-type"] || ""; - if (innerOptions.methods.indexOf(method) === -1) { - throw new Error("Method not allowed"); - } + if (innerOptions.methods.indexOf(method) === -1) { + throw new Error("Method not allowed"); + } - if (data) { - if (innerOptions.method === "get" && typeof data === "object") { - url += `?${serialize(data)}`; - } + if (data) { + if (innerOptions.method === "get" && typeof data === "object") { + url += `?${serialize(data)}`; + } - if (innerOptions.method !== "get") { - if (/json/gi.test(contentType)) { - innerOptions.body = JSON.stringify(data); + if (innerOptions.method !== "get") { + if (/json/gi.test(contentType)) { + innerOptions.body = JSON.stringify(data); + } else { + let formData; + if (data instanceof FormData) { + formData = data; } else { - let formData; - if (data instanceof FormData) { - formData = data; - } else { - formData = new FormData(); - for (let i in data) { - formData.append(i, data[i]); - } + formData = new FormData(); + for (let i in data) { + formData.append(i, data[i]); } - innerOptions.body = formData; } + innerOptions.body = formData; } } + } - let response = await fetch(parseUrl(url, opts), innerOptions); - - if (!response.ok) { - let err = new Error(response.statusText); - err.response = response; - throw err; - } + let response = await fetch(parseUrl(url, opts), innerOptions); - if (innerOptions.resolveWithFullResponse) { - return response; - } + if (!response.ok) { + let err = new Error(response.statusText); + err.response = response; + throw err; + } - if (/text/gi.test(acceptType)) { - return response.text(); - } + if (innerOptions.resolveWithFullResponse) { + return response; + } - if (/json/gi.test(acceptType)) { - return response.json(); - } + if (/text/gi.test(acceptType)) { + return response.text(); + } - return response; + if (/json/gi.test(acceptType)) { + return response.json(); } - request.new = (baseUrl, options) => Request(baseUrl, { ...opts, ...options }); + return response; + } - request.options = (key, value) => { - let result = opts; + request.new = (baseUrl, options) => Request(baseUrl, { ...opts, ...options }); - if (typeof key === "undefined") { - return result; - } + request.options = (key, value) => { + let result = opts; - let parsed = key.split("."); - let next; + if (typeof key === "undefined") { + return result; + } - while (parsed.length) { - next = parsed.shift(); + let parsed = key.split("."); + let next; - let nextIsArray = next.indexOf("[") > -1; - if (nextIsArray) { - let idx = next.replace(/\D/gi, ""); - next = next.split("[")[0]; - parsed.unshift(idx); - } + while (parsed.length) { + next = parsed.shift(); - if (parsed.length > 0 && typeof result[next] !== "object") { - result[next] = nextIsArray ? [] : {}; - } + let nextIsArray = next.indexOf("[") > -1; + if (nextIsArray) { + let idx = next.replace(/\D/gi, ""); + next = next.split("[")[0]; + parsed.unshift(idx); + } - if (parsed.length === 0 && typeof value !== "undefined") { - result[next] = value; - } + if (parsed.length > 0 && typeof result[next] !== "object") { + result[next] = nextIsArray ? [] : {}; + } - result = result[next]; + if (parsed.length === 0 && typeof value !== "undefined") { + result[next] = value; } - return result; - }; + result = result[next]; + } - opts.methods.forEach((method) => (request[method] = (url, data, options) => request(method, url, data, options))); + return result; + }; - return request; - } + opts.methods.forEach((method) => (request[method] = (url, data, options) => request(method, url, data, options))); + + return request; +} - v.request = Request(); -}; +const request = Request(); -plugin.default = plugin; -module.exports = plugin; +request.default = request; +module.exports = request; diff --git a/plugins/router.js b/plugins/router.js index 094ff44..f87d778 100644 --- a/plugins/router.js +++ b/plugins/router.js @@ -1,279 +1,244 @@ -let plugin = function(v) { - function flat(array) { - return Array.isArray(array) ? array.flat(Infinity) : [array]; +function flat(array) { + return Array.isArray(array) ? array.flat(Infinity) : [array]; +} + +let addPath = (router, method, path, middlewares, i) => { + if (middlewares.length === 0) { + return; } - let addPath = (router, method, path, middlewares, i) => { - if (middlewares.length === 0) { - return; - } + let realpath = path.replace(/(\S)(\/+)$/, "$1"); + + // Find the express like params + let params = realpath.match(/:(\w+)?/gi) || []; + + // Set the names of the params found + for (i in params) { + params[i] = params[i].slice(1); + } + + let regexpPath = "^" + realpath.replace(/:(\w+)/gi, "([^\\/\\s]+)") + "$"; + + router.paths.push({ + method, + path: realpath, + middlewares: flat(middlewares), + params, + regexp: new RegExp(regexpPath, "i") + }); +}; - let realpath = path.replace(/(\S)(\/+)$/, "$1"); +function parseQuery(queryParts) { + let parts = queryParts ? queryParts.split("&", 20) : []; + let query = {}; + let i = 0; + let nameValue; - // Find the express like params - let params = realpath.match(/:(\w+)?/gi) || []; + for (; i < parts.length; i++) { + nameValue = parts[i].split("=", 2); + query[nameValue[0]] = nameValue[1]; + } + + return query; +} + +function searchMiddlewares(router, path) { + let i; + let k; + let item; + let match; + let key; + let middlewares = []; + let params = {}; + let matches = []; + router.params = {}; + router.path = ""; + router.matches = []; + + // Search for middlewares + for (i = 0; i < router.paths.length; i++) { + item = router.paths[i]; + + match = item.regexp.exec(path); + // If we found middlewares + if (Array.isArray(match)) { + middlewares.push.apply(middlewares, item.middlewares); + match.shift(); + + // Parse params + for (k = 0; k < item.params.length; k++) { + key = item.params[k]; + params[key] = match.shift(); + } + + while (match.length) { + matches.push(match.shift()); + } - // Set the names of the params found - for (i in params) { - params[i] = params[i].slice(1); + if (item.method === "get") { + router.path = item.path; + break; + } } + } - let regexpPath = "^" + realpath.replace(/:(\w+)/gi, "([^\\/\\s]+)") + "$"; + router.params = params; + router.matches = matches; - router.paths.push({ - method, - path: realpath, - middlewares: flat(middlewares), - params, - regexp: new RegExp(regexpPath, "i") - }); + return middlewares; +} + +async function searchComponent(router, middlewares) { + let response; + let req = { + params: router.params, + query: router.query, + url: router.url, + path: router.path, + matches: router.matches }; + let i = 0; - function parseQuery(queryParts) { - let parts = queryParts ? queryParts.split("&", 20) : []; - let query = {}; - let i = 0; - let nameValue; + for (; i < middlewares.length; i++) { + response = await middlewares[i](req, response); - for (; i < parts.length; i++) { - nameValue = parts[i].split("=", 2); - query[nameValue[0]] = nameValue[1]; + if (response !== undefined && (router.v.isComponent(response) || router.v.isVnodeComponent(response))) { + return response; } - - return query; + } +} + +class Router { + paths = []; + container = null; + url = ""; + query = {}; + options = {}; + current = ""; + params = {}; + matches = []; + + get(path, ...args) { + addPath(this, "get", path, args); + return this; } - function searchMiddlewares(router, path) { + use(...args) { + let path = typeof args[0] === "string" ? args.shift() : "/"; let i; let k; + let subrouter; let item; - let match; - let key; - let middlewares = []; - let params = {}; - let matches = []; - router.params = {}; - router.path = ""; - router.matches = []; - - // Search for middlewares - for (i = 0; i < router.paths.length; i++) { - item = router.paths[i]; - - match = item.regexp.exec(path); - // If we found middlewares - if (Array.isArray(match)) { - middlewares.push.apply(middlewares, item.middlewares); - match.shift(); - - // Parse params - for (k = 0; k < item.params.length; k++) { - key = item.params[k]; - params[key] = match.shift(); - } - - while (match.length) { - matches.push(match.shift()); - } - - if (item.method === "get") { - router.path = item.path; - break; + let subpath; + + for (i = 0; i < args.length; i++) { + subrouter = args[i]; + if (typeof subrouter === "function") { + addPath(this, "use", `${path}.*`, [subrouter]); + } else if (subrouter.paths) { + for (k = 0; k < subrouter.paths.length; k++) { + item = subrouter.paths[k]; + subpath = `${path}${item.path}`.replace(/^\/\//, "/"); + addPath(this, item.method, subpath, item.middlewares); } } } - router.params = params; - router.matches = matches; - - return middlewares; + return this; } - async function searchComponent(router, middlewares) { - let response; - let item = false; - let req = { - params: router.params, - query: router.query, - url: router.url, - path: router.path, - matches: router.matches - }; - let i = 0; - - for (; i < middlewares.length; i++) { - response = await middlewares[i](req, response); - - if (response !== undefined) { - if (!response.view && typeof response === "function") { - response.view = response; - } - - if (response.view) { - item = response; - break; - } + routes() { + let routes = []; + this.paths.forEach((path) => { + if (path.method === "get") { + routes.push(path.path); } - } - return item; + }); + return routes; } - v.Router = function() { - const router = { - paths: [], - get(path, ...args) { - addPath(router, "get", path, args); - return router; - }, - use(...args) { - let path = typeof args[0] === "string" ? args.shift() : "/"; - let i; - let k; - let subrouter; - let item; - let subpath; - - for (i = 0; i < args.length; i++) { - subrouter = args[i]; - if (typeof subrouter === "function") { - addPath(router, "use", `${path}.*`, [subrouter]); - } else if (subrouter.paths) { - for (k = 0; k < subrouter.paths.length; k++) { - item = subrouter.paths[k]; - subpath = `${path}${item.path}`.replace(/^\/\//, "/"); - addPath(router, item.method, subpath, item.middlewares); - } - } - } - - return router; - }, - async go(path) { - let parts = path.split("?", 2); - let urlParts = parts[0].replace(/(.+)\/$/, "$1"); - let queryParts = parts[1]; - router.url = path; + async go(path, parentComponent) { + if (!path) { + throw new Error("router.url.required"); + } - router.query = parseQuery(queryParts); + let parts = path.split("?", 2); + let urlParts = parts[0].replace(/(.+)\/$/, "$1"); + let queryParts = parts[1]; + this.url = path; + this.query = parseQuery(queryParts); - let middlewares = searchMiddlewares(router, urlParts); + let middlewares = searchMiddlewares(this, urlParts); - let component = await searchComponent(router, middlewares); + let component = await searchComponent(this, middlewares); - if (!component || !component.view) { - throw new Error(`The url ${path} requested wasn't found`); - } - - return component; - } - }; - return router; - }; - - let mainRouter; - let RoutesContainer; - async function runRoute(parentComponent, url, args) { - let response = await mainRouter.go(url); + if (!component) { + throw new Error(`The url ${path} requested wasn't found`); + } if (parentComponent) { - args.unshift(v(response, ...args)); - args.unshift({}); - response = parentComponent; + let childComponent = this.v.isVnodeComponent(component) ? component : this.v(component, {}); + if (this.v.isVnodeComponent(parentComponent)) { + parentComponent.children.push(childComponent); + } else { + parentComponent = this.v(parentComponent, {}, childComponent); + } + component = parentComponent; } - args.unshift(response); - - v.routes.params = mainRouter.params; - v.routes.query = mainRouter.query; - v.routes.url = mainRouter.url; - v.routes.path = mainRouter.path; - v.routes.matches = mainRouter.matches; - - if (!v.isNode) { + if (!this.v.isNodeJs) { window.history.pushState(null, null, url); } - args.unshift(RoutesContainer); - return v.mount.apply(v, args); - } - - v.routes = function(elementContainer, router) { - if (elementContainer && router) { - mainRouter = router; - RoutesContainer = elementContainer; - // Activate the use of the router - if (!v.isNode) { - function onPopStateGoToRoute() { - v.routes.go(document.location.pathname); - } - window.addEventListener("popstate", onPopStateGoToRoute, false); - onPopStateGoToRoute(); - } + if (this.v.current.component === component) { + return this.v.update(component); } - }; - v.routes.url = ""; - v.routes.params = {}; - v.routes.query = {}; - v.routes.path = ""; - v.routes.matches = []; + return this.v.mount(this.container, component); + } +} - v.routes.go = function(...args) { - let parentComponent; - let url; +function plugin(v) { + const mount = v.mount; + v.mount = (elementContainer, routerOrComponent) => { + if (routerOrComponent instanceof Router === false) { + return mount(elementContainer, routerOrComponent); + } - if (args[0]) { - let arg = args[0]; - let viewMethod = "view" in Object(arg) ? arg.view : arg; + routerOrComponent.container = elementContainer; + routerOrComponent.v = v; - if (typeof viewMethod === "function") { - parentComponent = args.shift(); + // Activate the use of the router + if (!v.isNodeJs) { + function onPopStateGoToRoute() { + routerOrComponent.go(document.location.pathname); } + window.addEventListener("popstate", onPopStateGoToRoute, false); + onPopStateGoToRoute(); } - if (typeof args[0] === "string") { - url = args.shift(); - } - - if (!url) { - throw new Error("v.router.url.required"); - } + v.directive("route", (url, vnode, oldnode) => { + vnode.props.href = url; + vnode.props.onclick = (e) => { + if (typeof url === "string" && url.length > 0) { + if (url.charAt(0) !== "/") { + let current = routerOrComponent.current.split("?", 2).shift().split("/"); + current.pop(); + url = `${current.join("/")}/${url}`; + } - return runRoute(parentComponent, url, args); - }; + routerOrComponent.go(url); + } + e.preventDefault(); + }; - v.routes.get = function() { - let routes = []; - mainRouter.paths.forEach((path) => { - if (path.method === "get") { - routes.push(path.path); - } + v.setAttribute("href", vnode, oldnode); + v.setAttribute("onclick", vnode, oldnode); }); - return routes; }; +} - v.directive("route", (url, vnode, oldnode) => { - vnode.props.href = url; - vnode.props.onclick = (e) => { - if (typeof url === "string" && url.length > 0) { - if (url.charAt(0) !== "/") { - let current = v.routes.current - .split("?", 2) - .shift() - .split("/"); - current.pop(); - url = `${current.join("/")}/${url}`; - } - - v.routes.go(url); - } - e.preventDefault(); - }; - - v.updateProperty("href", vnode, oldnode); - v.updateProperty("onclick", vnode, oldnode); - }); -}; +plugin.Router = Router; plugin.default = plugin; module.exports = plugin; diff --git a/plugins/signals.js b/plugins/signals.js index 2dce708..304ac01 100644 --- a/plugins/signals.js +++ b/plugins/signals.js @@ -1,147 +1,133 @@ -let plugin = function (v) { - let signals = new Map(); +let signals = new Map(); - function makeUnsubscribe(subscriptions, computed, handler, cleanup) { - if (typeof cleanup === "function") { - computed.cleanup = cleanup; - } - computed.unsubscribe = () => { - subscriptions.delete(handler); - computed.cleanup(); - }; +function makeUnsubscribe(subscriptions, computed, handler, cleanup) { + if (typeof cleanup === "function") { + computed.cleanup = cleanup; } + computed.unsubscribe = () => { + subscriptions.delete(handler); + computed.cleanup(); + }; +} - function createGetter(signal, subscriptions, getters, nameOrHandler, getter) { - if (typeof nameOrHandler === "function") { - if (subscriptions.has(nameOrHandler) === false) { - let computed = v.Signal(() => nameOrHandler(signal.value)); - let cleanup = computed(); // Execute to register itself - makeUnsubscribe(subscriptions, computed, nameOrHandler, cleanup); - subscriptions.set(nameOrHandler, computed); - } - - return subscriptions.get(nameOrHandler); +function createGetter(signal, subscriptions, getters, nameOrHandler, getter) { + if (typeof nameOrHandler === "function") { + if (subscriptions.has(nameOrHandler) === false) { + // eslint-disable-next-line no-use-before-define + let computed = Signal(() => nameOrHandler(signal.value)); + let cleanup = computed(); // Execute to register itself + makeUnsubscribe(subscriptions, computed, nameOrHandler, cleanup); + subscriptions.set(nameOrHandler, computed); } - if (nameOrHandler in getters) { - throw new Error("Named computed already exists."); - } + return subscriptions.get(nameOrHandler); + } - getters[nameOrHandler] = getter; + if (nameOrHandler in getters) { + throw new Error("Named computed already exists."); } - // eslint-disable-next-line sonarjs/cognitive-complexity - v.Signal = function (value, key) { - if (typeof key !== "undefined" && signals.has(key)) { - let signal = signals.get(key); - signal.cleanup(); - return signal; - } + getters[nameOrHandler] = getter; +} - let subscriptions = new Map(); - let getters = {}; +// eslint-disable-next-line sonarjs/cognitive-complexity +function Signal(value, key) { + if (typeof key !== "undefined" && signals.has(key)) { + let signal = signals.get(key); + signal.cleanup(); + return signal; + } + + let subscriptions = new Map(); + let getters = {}; - let forceUpdate = false; + let forceUpdate = false; - let signal = new Proxy( - function (valOrPath, handler) { - if (typeof valOrPath === "undefined") { - return signal.value; - } else if (typeof valOrPath === "function") { - return createGetter(signal, subscriptions, getters, valOrPath); - } else if ( - typeof valOrPath === "string" && - typeof handler !== "undefined" - ) { - let parsed = valOrPath.split("."); - let result = signal.value; - let next; - while (parsed.length) { - next = parsed.shift(); - if (parsed.length > 0) { - if (typeof result[next] !== "object") { - result[next] = {}; - } - result = result[next]; - } else { - result[next] = - typeof handler === "function" ? handler(result[next]) : handler; + let signal = new Proxy( + function (valOrPath, handler) { + if (typeof valOrPath === "undefined") { + return signal.value; + } else if (typeof valOrPath === "function") { + return createGetter(signal, subscriptions, getters, valOrPath); + } else if (typeof valOrPath === "string" && typeof handler !== "undefined") { + let parsed = valOrPath.split("."); + let result = signal.value; + let next; + while (parsed.length) { + next = parsed.shift(); + if (parsed.length > 0) { + if (typeof result[next] !== "object") { + result[next] = {}; } + result = result[next]; + } else { + result[next] = typeof handler === "function" ? handler(result[next]) : handler; } - forceUpdate = true; - signal.value = signal.value; - } else { - signal.value = valOrPath; } - }, - { - set(state, prop, val) { - if ( - prop === "value" || - prop === "unsubscribe" || - prop === "cleanup" - ) { - let old = state[prop]; - state[prop] = val; - if (prop === "value" && (forceUpdate || val !== old)) { - forceUpdate = false; - for (let [handler, computed] of subscriptions) { - computed.cleanup(); - let cleanup = handler(val); - makeUnsubscribe(subscriptions, computed, handler, cleanup); - } + forceUpdate = true; + signal.value = signal.value; + } else { + signal.value = valOrPath; + } + }, + { + set(state, prop, val) { + if (prop === "value" || prop === "unsubscribe" || prop === "cleanup") { + let old = state[prop]; + state[prop] = val; + if (prop === "value" && (forceUpdate || val !== old)) { + forceUpdate = false; + for (let [handler, computed] of subscriptions) { + computed.cleanup(); + let cleanup = handler(val); + makeUnsubscribe(subscriptions, computed, handler, cleanup); } - return true; - } - }, - get(state, prop) { - if (prop === "value") { - return typeof state.value === "function" - ? state.value() - : state.value; } + return true; + } + }, + get(state, prop) { + if (prop === "value") { + return typeof state.value === "function" ? state.value() : state.value; + } - if ( - prop === "cleanup" || - prop === "unsubscribe" || - prop === "getter" - ) { - return state[prop]; - } + if (prop === "cleanup" || prop === "unsubscribe" || prop === "getter") { + return state[prop]; + } - if (prop in getters) { - return getters[prop](state.value); - } + if (prop in getters) { + return getters[prop](state.value); } } - ); + } + ); - Object.defineProperties(signal, { - value: { value, writable: true, enumerable: true }, - cleanup: { - value() { - for (let [handler, computed] of subscriptions) { - computed.unsubscribe(); - } - }, - writable: true, - enumerable: true + Object.defineProperties(signal, { + value: { value, writable: true, enumerable: true }, + cleanup: { + value() { + // eslint-disable-next-line no-unused-vars + for (let [handler, computed] of subscriptions) { + computed.unsubscribe(); + } }, - getter: { - value(name, handler) { - createGetter(signal, subscriptions, getters, name, handler); - }, - enumerable: true - } - }); - - if (typeof key !== "undefined") { - signals.set(key, signal); + writable: true, + enumerable: true + }, + getter: { + value(name, handler) { + createGetter(signal, subscriptions, getters, name, handler); + }, + enumerable: true } + }); - return signal; - }; -}; + if (typeof key !== "undefined") { + signals.set(key, signal); + } + + return signal; +} -plugin.default = plugin; -module.exports = plugin; +Signal.default = Signal; +module.exports = Signal; diff --git a/plugins/store.js b/plugins/store.js index d7fbb13..18ce469 100644 --- a/plugins/store.js +++ b/plugins/store.js @@ -1,78 +1,95 @@ -let plugin = function (v) { - function keyExists(objectname, object, key) { - if (key in object === false) { - throw new Error(`The ${objectname} "${key}" does not exists.`); - } +let update = () => {}; +let current = {}; + +function keyExists(objectname, object, key) { + if (key in object === false) { + throw new Error(`The ${objectname} "${key}" does not exists.`); } +} - function deepFreeze(obj) { - if (typeof obj === "object" && obj !== null && !Object.isFrozen(obj)) { - if (Array.isArray(obj)) { - for (let i = 0, l = obj.length; i < l; i++) { - deepFreeze(obj[i]); - } - } else { - for (let prop in obj) { - deepFreeze(obj[prop]); - } +function deepFreeze(obj) { + if (typeof obj === "object" && obj !== null && !Object.isFrozen(obj)) { + if (Array.isArray(obj)) { + for (let i = 0, l = obj.length; i < l; i++) { + deepFreeze(obj[i]); + } + } else { + for (let prop in obj) { + deepFreeze(obj[prop]); } - Object.freeze(obj); } - - return obj; + Object.freeze(obj); } - v.Store = function ({ state = {}, getters = {}, actions = {}, mutations = {} } = {}) { - let frozen = true; + return obj; +} - function isUnfrozen() { - if (frozen) { - throw new Error("You need to commit a mutation to change the state"); - } +function Store({ state = {}, getters = {}, actions = {}, mutations = {} } = {}) { + let frozen = true; + + function isUnfrozen() { + if (frozen) { + throw new Error("You need to commit a mutation to change the state"); } + } - let localState = typeof state === "function" ? state() : state; + let localState = typeof state === "function" ? state() : state; - this.state = new Proxy(localState || {}, { - get: (state, prop) => deepFreeze(state[prop]), - set: (state, prop, value) => { - isUnfrozen(); - state[prop] = value; - return true; - }, - deleteProperty: (state, prop) => { - isUnfrozen(); - delete state[prop]; - return true; - } - }); + this.state = new Proxy(localState || {}, { + get: (state, prop) => deepFreeze(state[prop]), + set: (state, prop, value) => { + isUnfrozen(); + state[prop] = value; + return true; + }, + deleteProperty: (state, prop) => { + isUnfrozen(); + delete state[prop]; + return true; + } + }); - this.getters = new Proxy(getters, { - get: (getters, getter) => { - try { - return getters[getter](this.state, this.getters); - } catch (e) { - // Getters should fail silently - } + this.getters = new Proxy(getters, { + get: (getters, getter) => { + try { + return getters[getter](this.state, this.getters); + } catch (e) { + // Getters should fail silently } - }); + } + }); - this.commit = (mutation, ...args) => { - keyExists("mutation", mutations, mutation); - frozen = false; - mutations[mutation](this.state, ...args); - frozen = true; - v.isMounted && v.update(); - }; + this.commit = (mutation, ...args) => { + keyExists("mutation", mutations, mutation); + frozen = false; + mutations[mutation](this.state, ...args); + frozen = true; + update(); + }; - this.dispatch = (action, ...args) => { - keyExists("action", actions, action); - return Promise.resolve(actions[action](this, ...args)); - }; + this.dispatch = (action, ...args) => { + keyExists("action", actions, action); + return Promise.resolve(actions[action](this, ...args)); }; +} - v.useStore = (store) => (v.$store = store instanceof v.Store ? store : new v.Store(store)); -}; +function plugin(v, options) { + current = v.current; + update = () => { + if (current.app) { + v.update(v.current.app.component); + } + }; + + if (options) { + v.store = new Store(options); + v.commit = v.store.commit.bind(v.store); + v.dispatch = v.store.dispatch.bind(v.store); + v.state = v.store.state; + v.getters = v.store.getters; + } +} +plugin.Store = Store; plugin.default = plugin; module.exports = plugin; diff --git a/plugins/sw.js b/plugins/sw.js index 6a3120b..59bee16 100644 --- a/plugins/sw.js +++ b/plugins/sw.js @@ -1,19 +1,30 @@ -let plugin = function (v) { - if (!v.isNode) { - v.sw = async function (file = v.sw.file, options = v.sw.options) { - await navigator.serviceWorker.register(file, options); +class Sw { + file = "/sw.js"; + options = { scope: "/" }; + ready = false; + sw = null; - v.sw.ready = true; - v.sw.file = file; - v.sw.options = options; - return navigator.serviceWorker; - }; + constructor(file, options) { + if (Boolean(typeof process !== "undefined" && process.versions && process.versions.node)) { + throw new Error("Service Worker registration not supported in node.js"); + return; + } - v.sw.ready = false; - v.sw.file = "/sw.js"; - v.sw.options = { scope: "/" }; + if (file) { + this.file = file; + } + if (options) { + this.options = options; + } } -}; -plugin.default = plugin; -module.exports = plugin; + async register() { + await navigator.serviceWorker.register(this.file, this.options); + this.ready = true; + this.sw = navigator.serviceWorker; + return this.sw; + } +} + +Sw.default = Sw; +module.exports = Sw; diff --git a/plugins/utils/tree-adapter.js b/plugins/utils/tree-adapter.js index 77dbe2d..c9a20b9 100644 --- a/plugins/utils/tree-adapter.js +++ b/plugins/utils/tree-adapter.js @@ -174,13 +174,20 @@ class Node { class Text extends Node { constructor(text) { super(3, "#text"); - this.textContent = text; + this.node_value = String(text); } + node_value = ""; set textContent(text) { - this.nodeValue = String(text); + this.node_value = String(text); } get textContent() { - return this.nodeValue; + return this.node_value; + } + set nodeValue(text) { + this.node_value = String(text); + } + get nodeValue() { + return this.node_value; } } @@ -363,8 +370,7 @@ class Element extends Node { cloneNode() { let div = document.createElement("div"); div.innerHTML = this.outerHTML; - let el = div.firstChild; - return el; + return div.firstChild; } get firstChild() { diff --git a/plugins/v-model.js b/plugins/v-model.js deleted file mode 100644 index da12623..0000000 --- a/plugins/v-model.js +++ /dev/null @@ -1,97 +0,0 @@ -let plugin = function (v) { - v.directive("model", ([model, property, event], vnode, oldvnode) => { - if (vnode.name === "input") { - event = event || "oninput"; - switch (vnode.props.type) { - case "checkbox": { - if (Array.isArray(model[property])) { - vnode.props[event] = (e) => { - let val = e.target.value; - let idx = model[property].indexOf(val); - if (idx === -1) { - model[property].push(val); - } else { - model[property].splice(idx, 1); - } - }; - vnode.props.checked = - model[property].indexOf(vnode.dom.value) !== -1; - } else if ("value" in vnode.props) { - vnode.props[event] = () => { - if (model[property] === vnode.props.value) { - model[property] = null; - } else { - model[property] = vnode.props.value; - } - }; - vnode.props.checked = model[property] === vnode.props.value; - } else { - vnode.props[event] = () => (model[property] = !model[property]); - vnode.props.checked = model[property]; - } - - v.updateProperty("checked", vnode, oldvnode); - break; - } - case "radio": { - vnode.props.checked = model[property] === vnode.dom.value; - v.updateProperty("checked", vnode, oldvnode); - break; - } - default: { - vnode.props.value = model[property]; - v.updateProperty("value", vnode, oldvnode); - } - } - } else if (vnode.name === "select") { - event = event || "onclick"; - if (vnode.props.multiple) { - vnode.props[event] = (e) => { - let val = e.target.value; - if (e.ctrlKey) { - let idx = model[property].indexOf(val); - if (idx === -1) { - model[property].push(val); - } else { - model[property].splice(idx, 1); - } - } else { - model[property].splice(0, model[property].length); - model[property].push(val); - } - }; - vnode.children.forEach((child) => { - if (child.name === "option") { - let value = - "value" in child.props - ? child.props.value - : child.children.join("").trim(); - child.props.selected = model[property].indexOf(value) !== -1; - } - }); - } else { - vnode.children.forEach((child) => { - if (child.name === "option") { - let value = - "value" in child.props - ? child.props.value - : child.children.join("").trim(); - child.props.selected = value === model[property]; - } - }); - } - } else if (vnode.name === "textarea") { - event = event || "oninput"; - vnode.children = [model[property]]; - } - - if (!vnode.props[event]) { - vnode.props[event] = (e) => (model[property] = e.target.value); - } - - v.updateProperty(event, vnode, oldvnode); - }); -}; - -plugin.default = plugin; -module.exports = plugin; diff --git a/register.js b/register.js index 0bbafd4..f0466fb 100644 --- a/register.js +++ b/register.js @@ -1,6 +1,5 @@ const { addHook } = require("pirates"); const { transformSync } = require("esbuild"); -const fs = require("fs"); addHook( (code, filePath) => { @@ -8,8 +7,8 @@ addHook( let extension = fileName.split(".").pop(); let loader = "default"; - if (["js", "jsx", "ts", "tsx", "css", "json", "txt"].includes(extension)) { - if (["js", "jsx", "mjs", "ts", "tsx"].includes(extension)) { + if (["js", "cjs", "jsx", "ts", "tsx", "css", "json", "txt"].includes(extension)) { + if (["js", "cjs", "jsx", "mjs", "ts", "tsx"].includes(extension)) { loader = "tsx"; } else if (extension === "txt") { loader = "text"; @@ -21,49 +20,17 @@ addHook( } let options = { - tsconfigRaw: { - compilerOptions: { - target: "ESNEXT", - module: "ESNEXT", - strict: true, - allowSyntheticDefaultImports: true, - allowJs: true, - esModuleInterop: true, - resolveJsonModule: true - } - }, - loader, + sourcefile: filePath, + sourcemap: "inline", minify: false, - format: "cjs", target: "esnext", - logLevel: "warning", + loader: loader, jsxFactory: "v", - jsxFragment: "v.fragment" - }; - - // Check if tsconfig.json exists with fs module - if ((extension === "ts" || extension === "tsx") && fs.existsSync(process.cwd() + "/tsconfig.json")) { - let tsconfig = fs.readFileSync(process.cwd() + "/tsconfig.json", "utf8"); + jsxFragment: "v.fragment", - let tsconfigRaw = JSON.parse(tsconfig); - let compilerOptions = tsconfigRaw.compilerOptions || {}; - - options.tsconfigRaw = { ...options.tsconfigRaw, ...tsconfigRaw }; - options.tsconfigRaw.compilerOptions = { ...options.tsconfigRaw.compilerOptions, ...compilerOptions }; - - if (compilerOptions.target) { - options.target = compilerOptions.target.toLowerCase(); - } - - if (compilerOptions.module) { - let format = compilerOptions.module.toLowerCase(); - if (format === "commonjs") { - options.format = "cjs"; - } else if (format.startsWith("es")) { - options.format = "esm"; - } - } - } + logLevel: "warning", + format: "cjs" + }; let { code: transformed } = transformSync(code, options); if (/"use strict"\;/gi.test(code) === false) { diff --git a/source.js b/source.js index c3161d6..5028669 100644 --- a/source.js +++ b/source.js @@ -1,25 +1,205 @@ -require("./register"); -let { inline } = require("./plugins/node"); -let { writeFileSync } = require("fs"); -const GzipSize = import("gzip-size"); -let { files } = require("./package.json"); - -async function run() { - const gzipSizeSync = (await GzipSize).gzipSizeSync; - inline.extensions("ts"); - await inline.ts("./lib/index.ts", { - compact: true, - declarationDir: "dist/@types", - tsc: { - include: files - } +const esbuild = require("esbuild"); +const terser = require("terser"); +const tsc = require("tsc-prog"); +const fs = require("fs"); +const zlib = require("zlib"); + +function convertToUMD(text, globalName) { + // HACK: convert to UMD - only supports cjs and global var + const varName = "__EXPORTS__"; + let code = text; + code = code.replace(/export\s*\{([^{}]+)\}/, (_, inner) => { + const defaultExport = inner.match(/^(\w+) as default$/); + return defaultExport != null ? `var ${varName}=${defaultExport[1]}` : `var ${varName}={${inner.replace(/(\w+) as (\w+)/g, "$2:$1")}}`; }); - let contents = inline.ts()[0].raw; - writeFileSync("./dist/valyrian.min.js", contents); - writeFileSync("./dist/valyrian.min.js.map", inline.ts()[0].map); + code = `(()=>{${code};typeof module!=='undefined'?module.exports=${varName}:self.${globalName}=${varName}})()`; + return code; +} + +function getSourceMap(contents) { + let mapBase64 = Buffer.from(contents.toString()).toString("base64"); + return `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapBase64}`; +} + +async function build({ globalName, entryPoint, outfileName, clean = false, minify = true, external = [], bundle = true }) { + try { + let header = `/************ ${entryPoint} ************/`; + console.log(""); + console.log(header); + + let tscProgOptions2 = { + basePath: process.cwd(), // always required, used for relative paths + configFilePath: "tsconfig.json", // config to inherit from (optional) + files: [entryPoint], + pretty: true, + copyOtherToOutDir: false, + clean: clean ? ["dist"] : [], + compilerOptions: { + rootDir: "./", + declaration: true, + declarationDir: "./dist/@types", + emitDeclarationOnly: true + } + }; + + tsc.build(tscProgOptions2); + let cjs = esbuild.buildSync({ + entryPoints: [entryPoint], + bundle, + sourcemap: "external", + write: false, + minify: false, + outdir: "out", + target: "esnext", + loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" }, + format: "cjs", + metafile: true, + external + }); + + let esm = esbuild.buildSync({ + entryPoints: [entryPoint], + bundle, + sourcemap: "external", + write: false, + minify: false, + outdir: "out", + target: "esnext", + loader: { ".js": "jsx", ".ts": "tsx", ".mjs": "jsx" }, + format: "esm", + metafile: true, + external + }); + + let esmContent = esm.outputFiles[1].text; + + // HACK: simulate __dirname and __filename for esm + if (esmContent.indexOf("__dirname") !== -1 || esmContent.indexOf("__filename") !== -1) { + esmContent = + `import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); ` + esmContent; + if (esmContent.indexOf("import path from") === -1) { + esmContent = `import path from 'path'; ` + esmContent; + } + } + + // ensure outdir exists or create it + let outdir = outfileName.split("/").slice(0, -1).join("/"); + if (!fs.existsSync(outdir)) { + fs.mkdirSync(outdir, { recursive: true }); + } + + fs.writeFileSync(`${outfileName}.js`, esmContent); + // fs.writeFileSync(`${outfileName}.mjs.map`, getSourceMap(esm.outputFiles[0].text)); + fs.writeFileSync(`${outfileName}.cjs`, cjs.outputFiles[1].text); + // fs.writeFileSync(`${outfileName}.js.map`, getSourceMap(cjs.outputFiles[0].text)); - console.log("Size:", contents.length); - console.log("Gzip:", gzipSizeSync(contents)); + let text = await esbuild.analyzeMetafile(esm.metafile, { verbose: true }); + console.log(text); + + let result2; + if (minify) { + let code = convertToUMD(esm.outputFiles[1].text, globalName); + result2 = await terser.minify(code, { + sourceMap: { + content: esm.outputFiles[0].text.toString() + }, + compress: { + booleans_as_integers: false + }, + output: { + wrap_func_args: false + }, + ecma: 2020 + }); + + fs.writeFileSync(`${outfileName}.min.js`, result2.code); + fs.writeFileSync(`${outfileName}.min.js.map`, getSourceMap(result2.map)); + } + + function formatBytesToKiloBytes(bytes) { + return (bytes / 1024).toFixed(2) + "kb"; + } + + console.log("Esm", formatBytesToKiloBytes(esm.outputFiles[1].text.length)); + if (minify) { + console.log("Minified:", formatBytesToKiloBytes(result2.code.length)); + // Get the size using gzip compression + const gzip = zlib.gzipSync(result2.code); + console.log("Gzip:", formatBytesToKiloBytes(gzip.length)); + // Get the size using brotli algorithm + const brotli = zlib.brotliCompressSync(result2.code); + console.log("Brotli:", formatBytesToKiloBytes(brotli.length)); + } + console.log(`/${Array(header.length).fill("*").join("")}/`); + } catch (e) { + console.error(e); + } } -run(); +(async () => { + await build({ + globalName: "Valyrian", + entryPoint: "./lib/index.ts", + outfileName: "./dist/index", + clean: true, + minify: true, + bundle: true + }); + + // await build({ + // globalName: "ValyrianHooks", + // entryPoint: "./plugins/hooks.ts", + // outfileName: "./dist/hooks", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: "ValyrianRequest", + // entryPoint: "./plugins/request.js", + // outfileName: "./dist/request", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: "ValyrianRouter", + // entryPoint: "./plugins/router.js", + // outfileName: "./dist/router", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: "ValyrianSignals", + // entryPoint: "./plugins/signals.js", + // outfileName: "./dist/signals", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: "ValyrianStore", + // entryPoint: "./plugins/store.js", + // outfileName: "./dist/store", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: "ValyrianSw", + // entryPoint: "./plugins/sw.js", + // outfileName: "./dist/sw", + // clean: false, + // minify: false + // }); + + // await build({ + // globalName: 'ValyrianSignals', + // entryPoint: './plugins/signals.js', + // outfileName: './dist/signals', + // clean: false, + // minify: false, + // external: ['child_process', 'fs', 'os', 'path'] + // }); +})(); diff --git a/test/directives_test.js b/test/directives_test.js index 9ae29e7..deaf13c 100644 --- a/test/directives_test.js +++ b/test/directives_test.js @@ -1,27 +1,20 @@ const expect = require("expect"); -const faker = require("faker"); const dayjs = require("dayjs"); -import "../lib"; +const { v } = require("../lib/index"); -const nodePlugin = require("../plugins/node"); -v.usePlugin(nodePlugin); +const plugin = require("../plugins/node"); +v.use(plugin); // eslint-disable-next-line max-lines-per-function describe("Directives", () => { describe("Directive creation", () => { - let result; - it("should be able create a directive", () => { + let result; let expected = "Hello world"; + v.directive("test", (value) => (result = `Hello ${value}`)); - v.mount("div", () =>
); - expect(result).toEqual(expected); - }); - it("should not be able overwrite a directive", () => { - let expected = "Hello world"; - v.directive("test", () => (result = "Something else")); v.mount("div", () =>
); expect(result).toEqual(expected); }); @@ -30,16 +23,18 @@ describe("Directives", () => { let newVnode; let oldVnode; - v.directive("test2", (v, vnode, oldvnode) => { + let app = () =>
; + + v.directive("test2", (v, vnode, old) => { newVnode = vnode; - oldVnode = oldvnode; + oldVnode = old; }); - v.mount("div", () =>
); - v.update(); + v.mount("div", app); + v.update(app); expect(newVnode).toEqual({ - name: "div", + tag: "div", props: { "v-test2": true }, @@ -49,7 +44,7 @@ describe("Directives", () => { }); expect(oldVnode).toEqual({ - name: "div", + tag: "div", props: { "v-test2": true }, @@ -60,59 +55,66 @@ describe("Directives", () => { }); it("should be able to identify if this is first render or update", () => { - v.directive("create", (placeholder, vnode, oldvnode) => { - if (!oldvnode) { + let app = () =>
; + + v.directive("create", (v, vnode, oldVnode) => { + if (!oldVnode) { vnode.children = ["First render, vnode created"]; } else { vnode.children = ["Second render, vnode updated"]; } }); - let component = () =>
; - let result = v.mount("body", component); + let result = v.mount("body", app); + expect(result).toEqual("
First render, vnode created
"); - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual("
Second render, vnode updated
"); }); it("should be able to modify the children of a vnode", () => { let expected = "
Hello world
"; - v.directive("test3", (v, vnode) => (vnode.children = ["Hello world"])); - let result = v.mount("div", () => ( + + v.directive("test3", (v, vnode) => { + vnode.children = ["Hello world"]; + }); + + let app = () => (
Hello John Doe
- )); + ); + + let result = v.mount("div", app); expect(result).toEqual(expected); }); /** * Modify properties is not guaranteed because the properties are processed by place - * If the directive needs to do update previous properties you need to update the property using the v.updateProperty method + * If the directive needs to update previous properties you need to update the property using the setAttribute method */ it("Modify properties is not guaranteed", () => { let update = false; - v.directive("test4", (p, vnode, oldVnode) => { + let app = () =>
; + + v.directive("test4", (value, vnode, oldVnode) => { // Try to change u property vnode.props.u = "property changed"; if (update) { - if (oldVnode || v.addProperty === undefined) { - v.updateProperty("u", vnode, oldVnode); - } else { - v.addProperty("u", vnode); - } + console.log(v); + v.setAttribute("u", "property changed", vnode, oldVnode); } // Try to change x property vnode.props.x = "property changed"; }); - let result = v.mount("div", () =>
); + + let result = v.mount("div", app); expect(result).toEqual('
'); - v.unMount(); update = true; - let result2 = v.mount("div", () =>
); + let result2 = v.mount("div", app); expect(result2).toEqual('
'); }); @@ -126,7 +128,7 @@ describe("Directives", () => { let formatDate = (value) => dayjs(value).format("MMMM D, YYYY"); v.directive("date-inline", (date, vnode) => (vnode.children = [formatDate(date)])); - v.directive("date", (v, vnode) => (vnode.children = [formatDate(vnode.children[0])])); + v.directive("date", (_, vnode) => (vnode.children = [formatDate(vnode.children[0])])); let date = "08-16-2018"; let result = v.mount("div", () =>
); @@ -204,7 +206,7 @@ describe("Directives", () => { */ describe("v-for", () => { it("should create 10 list items", () => { - let items = faker.lorem.words(10).split(" "); + let items = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa"]; let expected = "
    " + items.reduce((str, word) => str + `
  • ${word}
  • `, "") + "
"; let result = v.mount("body", () =>
    {(word) =>
  • {word}
  • }
); @@ -212,7 +214,7 @@ describe("Directives", () => { }); it("should create 10 list items getting its index", () => { - let items = faker.lorem.words(10).split(" "); + let items = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa"]; let i = 0; let expected = "
    " + items.reduce((str, word) => str + `
  • ${i++} - ${word}
  • `, "") + "
"; let result = v.mount("body", () => ( @@ -240,7 +242,6 @@ describe("Directives", () => { let expected = "
Hello world
"; values.forEach((value) => { - v.unMount(); let result = v.mount("div", () => (
Hello world @@ -256,7 +257,6 @@ describe("Directives", () => { let expected = "
"; values.forEach((value) => { - v.unMount(); let result = v.mount("div", () => (
Hello world @@ -271,15 +271,16 @@ describe("Directives", () => { let expected1 = "
Hello world
"; let expected2 = "
"; - let result1 = v.mount("div", () => ( + let app = () => (
Hello world
- )); + ); + let result1 = v.mount("div", app); expect(result1).toEqual(expected1); value = false; - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual(expected2); }); }); @@ -298,7 +299,6 @@ describe("Directives", () => { let expected = "
Hello world
"; values.forEach((value) => { - v.unMount(); let result = v.mount("div", () => (
Hello world @@ -314,7 +314,6 @@ describe("Directives", () => { let expected = "
"; values.forEach((value) => { - v.unMount(); let result = v.mount("div", () => (
Hello world @@ -364,11 +363,12 @@ describe("Directives", () => { world: true }; - let result = v.mount("body", () =>
); + let app = () =>
; + let result = v.mount("body", app); expect(result).toEqual('
'); classes.world = false; - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual("
"); }); @@ -376,32 +376,32 @@ describe("Directives", () => { let classes = { world: true }; - - let result = v.mount("body", () =>
); + let app = () =>
; + let result = v.mount("body", app); expect(result).toEqual('
'); classes.world = false; - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual('
'); }); }); /** * The directive v-once is used to render just once and skip all subsequent render updates - * Similar to write the lifecycle onbeforeupdate={() => false} + * Similar to write the lifecycle shouldupdate={() => false} */ describe("v-once", () => { it("should not update the dom after first render", () => { let Store = { hello: "world" }; - let Component = () =>
Hello {Store.hello}
; + let app = () =>
Hello {Store.hello}
; - let result = v.mount("body", Component); + let result = v.mount("body", app); expect(result).toEqual("
Hello world
"); // We update our store Store.hello = "John Doe"; - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual("
Hello world
"); }); }); @@ -419,9 +419,6 @@ describe("Directives", () => { expect(result).toEqual("
Hello world
"); - // Unmount to clean the instance - v.unMount(); - // Using v-html directive let Component2 = () =>
; let result2 = v.mount("body", Component2); @@ -436,29 +433,29 @@ describe("Directives", () => { it("should use v-if with v-for directives", () => { let arr = [1, 2, 3, 4]; let show = true; - let component = () => ( + let app = () => (
{(i) => {i}}
); - let result = v.mount("body", component); + let result = v.mount("body", app); expect(result).toEqual("
1234
"); show = false; - let result2 = v.update(); + let result2 = v.update(app); expect(result2).toEqual(""); }); }); /** - * The data directive is used just to pass data without creating an attribute on the node. + * The state directive is used just to pass data without creating an attribute on the node. * And its main use is in the lifecycle methods to validate properties or changes */ - describe("reserved word data", () => { + describe("reserved word state", () => { it("should not render an attribute", () => { - let data = { hello: "world" }; - let Component = () =>
oldVnode.props.data.hello !== newVnode.props.data.hello} />; + let state = { hello: "world" }; + let Component = () =>
oldVnode.props.state.hello !== newVnode.props.state.hello} />; let result = v.mount("body", Component); expect(result).toEqual("
"); diff --git a/test/hooks_test.js b/test/hooks_test.js index 948244d..a58d416 100644 --- a/test/hooks_test.js +++ b/test/hooks_test.js @@ -1,19 +1,19 @@ -import "../lib"; +import nodePlugin from "../plugins/node"; + +import { v } from "../lib/index"; +import plugin, { useEffect, useState, useRef, useCallback, useMemo } from "../plugins/hooks"; import expect from "expect"; -import hooksPlugin from "../plugins/hooks"; -import nodePlugin from "../plugins/node"; +import { v } from "../lib"; -v.usePlugin(nodePlugin); -v.usePlugin(hooksPlugin); +v.use(plugin); +v.use(nodePlugin); -describe("Hooks", () => { +describe.only("Hooks", () => { describe("State hook", () => { it("should handle a component state", async () => { - v.unMount(); - let Counter = () => { - let [count, setCount] = v.useState(0); + let [count, setCount] = useState(0); let interval = setInterval(() => setCount(count + 1), 1000); v.onCleanup(() => clearInterval(interval)); return
{count}
; @@ -22,23 +22,21 @@ describe("Hooks", () => { let result = v.mount("div", Counter); expect(result).toEqual("
0
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Counter); expect(result).toEqual("
2
"); - result = v.unMount(); + v.unmount(Counter); }); - it("should handle subcomponents state and cleanup", async () => { - v.unMount(); - + it("should handle subcomponents state and v.onCleanup", async () => { let Ok = () => { - let [ok, setOk] = v.useState("ok"); + let [ok, setOk] = useState("ok"); let interval = setInterval(() => setOk("not ok"), 1000); v.onCleanup(() => clearInterval(interval)); return
{ok}
; }; let Counter = () => { - let [count, setCount] = v.useState(0); + let [count, setCount] = useState(0); let interval = setInterval(() => setCount(count + 1), 1000); v.onCleanup(() => clearInterval(interval)); return ( @@ -51,16 +49,14 @@ describe("Hooks", () => { let result = v.mount("div", Counter); expect(result).toEqual("
0
ok
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Counter); expect(result).toEqual("
2
not ok
"); - result = v.unMount(); + v.unmount(Counter); }); it("array getter-setter based state", async () => { - v.unMount(); - let Counter = () => { - let [count, setCount] = v.useState(0); + let [count, setCount] = useState(0); let interval = setInterval(() => setCount(count + 1), 1000); v.onCleanup(() => clearInterval(interval)); return
{count}
; @@ -69,9 +65,9 @@ describe("Hooks", () => { let result = v.mount("div", Counter); expect(result).toEqual("
0
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Counter); expect(result).toEqual("
2
"); - result = v.unMount(); + v.unmount(Counter); }); }); @@ -79,7 +75,7 @@ describe("Hooks", () => { it("should call the effect at first render", () => { let count = 0; let Component = function () { - v.useEffect(() => count++); + useEffect(() => count++); return
{count}
; }; @@ -87,23 +83,23 @@ describe("Hooks", () => { expect(response).toEqual("
1
"); }); - it("should call the effect at every update", () => { + it("should call the effect at every v.update", () => { let count = 0; let Component = function () { - v.useEffect(() => count++); + useEffect(() => count++); return
{count}
; }; let response = v.mount("body", Component); expect(response).toEqual("
1
"); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
2
"); }); - it("should handle cleanup", () => { + it("should handle v.onCleanup", () => { let count = 0; let Component = function () { - v.useEffect(() => { + useEffect(() => { count++; return () => (count -= 2); }); @@ -112,40 +108,53 @@ describe("Hooks", () => { let response = v.mount("body", Component); expect(response).toEqual("
1
"); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
0
"); }); it("should not call the effect if the change array is passed and there are no changes", () => { let count = 0; let Component = function () { - v.useEffect(() => count++, [0]); + useEffect(() => count++, [1]); return
{count}
; }; let response = v.mount("body", Component); expect(response).toEqual("
1
"); - response = v.update(); + response = v.update(Component); + expect(response).toEqual("
1
"); + }); + + it("should not call the effect if the change array is passed and is an empty array", () => { + let count = 0; + let Component = function () { + useEffect(() => count++, []); + return
{count}
; + }; + + let response = v.mount("body", Component); + expect(response).toEqual("
1
"); + response = v.update(Component); expect(response).toEqual("
1
"); }); it("should call the effect if the change array is passed and there are changes", () => { let count = 0; let Component = function () { - v.useEffect(() => count++, [count]); + useEffect(() => count++, [count]); return
{count}
; }; let response = v.mount("body", Component); expect(response).toEqual("
1
"); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
2
"); }); - it("should call cleanup even if the changes array is passed and there are changes", () => { + it("should call v.onCleanup even if the changes array is passed and there are changes", () => { let count = 0; let Component = function () { - v.useEffect(() => { + useEffect(() => { count++; return () => count++; }, [count]); @@ -154,16 +163,16 @@ describe("Hooks", () => { let response = v.mount("body", Component); expect(response).toEqual("
1
"); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
3
"); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
5
"); }); - it("should handle cleanup on unMount", () => { + it("should handle v.onCleanup on unMount", () => { let count = 0; let Component = function () { - v.useEffect(() => { + useEffect(() => { count++; return () => (count -= 2); }); @@ -174,13 +183,179 @@ describe("Hooks", () => { expect(response).toEqual("
1
"); expect(count).toEqual(1); - response = v.update(); + response = v.update(Component); expect(response).toEqual("
0
"); expect(count).toEqual(0); - response = v.unMount(); + response = v.unmount(Component); expect(response).toEqual(""); expect(count).toEqual(-2); }); + + it("should call the effect only in the v.unmount", () => { + let count = 0; + let Component = function () { + useEffect(() => { + count++; + }, null); + return
{count}
; + }; + + let response = v.mount("body", Component); + expect(response).toEqual("
0
"); + expect(count).toEqual(0); + + response = v.update(Component); + expect(response).toEqual("
0
"); + expect(count).toEqual(0); + + response = v.unmount(Component); + expect(response).toEqual(""); + expect(count).toEqual(1); + }); + + describe("Compare lifecycle vs hooks", () => { + let lifecycleCount = 0; + let plusLifeCycle = () => (lifecycleCount += 1); + + let hooksCount = 0; + let plusHooks = () => (hooksCount += 1); + + let LifecycleComponent = () => { + return ( +
+ Hello world +
+ ); + }; + + let HooksComponent = () => { + // useEffect(plusHooks, []); // Only create replaced by the next line + useEffect(plusHooks); // Create & v.update + useEffect(plusHooks, null); // Remove + return
Hello world
; + }; + + it("should call the lifecycle", () => { + v.mount("body", LifecycleComponent); + expect(lifecycleCount).toEqual(1); + v.update(LifecycleComponent); + expect(lifecycleCount).toEqual(2); + v.unmount(LifecycleComponent); + expect(lifecycleCount).toEqual(3); + }); + + it("should call the hooks", () => { + v.mount("body", HooksComponent); + expect(hooksCount).toEqual(1); + v.update(HooksComponent); + expect(hooksCount).toEqual(2); + v.unmount(HooksComponent); + expect(hooksCount).toEqual(3); + }); + }); + }); + + describe("Ref hook", () => { + it("should return a ref", () => { + let ref; + let updated = false; + let Component = function () { + ref = useRef(null); + if (!updated) { + expect(ref.current).toEqual(null); + } + return
Hello world
; + }; + + let response = v.mount("body", Component); + expect(response).toEqual("
Hello world
"); + expect(ref.current).not.toEqual(null); + + let refCurrent = ref.current; + updated = true; + v.update(Component); + expect(refCurrent === ref.current).toEqual(true); + }); + }); + + describe("Callback hook", () => { + it("should test the callback problem", () => { + let callback; + let Component = function () { + callback = () => {}; + return
Hello world
; + }; + + let response = v.mount("body", Component); + expect(response).toEqual("
Hello world
"); + expect(callback).not.toEqual(null); + + let oldCallback = callback; + v.update(Component); + expect(oldCallback === callback).toEqual(false); + }); + + it("should call the callback", () => { + let callback; + let Component = function () { + callback = useCallback(() => {}, []); + return
Hello world
; + }; + let response = v.mount("body", Component); + expect(response).toEqual("
Hello world
"); + expect(callback).not.toEqual(null); + let oldCallback = callback; + v.update(Component); + expect(oldCallback === callback).toEqual(true); + }); + }); + + describe("Memo hook", () => { + it("should test the memo problem", () => { + let computedTimes = 0; + let color = "red"; + let Component = function () { + computedTimes++; + return
Hello world
; + }; + + let response = v.mount("body", Component); + expect(response).toEqual('
Hello world
'); + expect(computedTimes).toEqual(1); + + let response2 = v.update(Component); + expect(response2).toEqual('
Hello world
'); + expect(computedTimes).toEqual(2); + + color = "blue"; + let response3 = v.update(Component); + expect(response3).toEqual('
Hello world
'); + expect(computedTimes).toEqual(3); + }); + + it("should use the memo", () => { + let computedTimes = 0; + let color = "red"; + let Component = function () { + return useMemo(() => { + computedTimes++; + return
; + }, [color]); + }; + + let response = v.mount("body", Component); + expect(response).toEqual('
'); + expect(computedTimes).toEqual(1); + + let response2 = v.update(Component); + expect(response2).toEqual('
'); + expect(computedTimes).toEqual(1); + + color = "blue"; + let response3 = v.update(Component); + expect(response3).toEqual('
'); + expect(computedTimes).toEqual(2); + }); }); }); diff --git a/test/hyperscript_test.js b/test/hyperscript_test.js index 83cf629..9e2a203 100644 --- a/test/hyperscript_test.js +++ b/test/hyperscript_test.js @@ -1,14 +1,13 @@ -import "../lib"; - import expect from "expect"; import nodePlugin from "../plugins/node"; +import { v } from "../lib"; -v.usePlugin(nodePlugin); +v.use(nodePlugin); describe("Hyperscript", () => { it("should create a div element", () => { expect(v("div")).toEqual({ - name: "div", + tag: "div", props: {}, children: [] }); @@ -16,7 +15,7 @@ describe("Hyperscript", () => { it("should create a div element with a text child", () => { expect(v("div", null, "Hello")).toEqual({ - name: "div", + tag: "div", props: {}, children: ["Hello"] }); @@ -24,11 +23,11 @@ describe("Hyperscript", () => { it("should create a div element with an element child", () => { expect(v("div", null, v("span"))).toEqual({ - name: "div", + tag: "div", props: {}, children: [ { - name: "span", + tag: "span", props: {}, children: [] } @@ -38,7 +37,7 @@ describe("Hyperscript", () => { it("should create a div element with comma separated children", () => { expect(v("div", null, "Hello ", "world")).toEqual({ - name: "div", + tag: "div", props: {}, children: ["Hello ", "world"] }); @@ -46,7 +45,7 @@ describe("Hyperscript", () => { it("should create a div element with array of children", () => { expect(v("div", null, ["Hello ", "world"])).toEqual({ - name: "div", + tag: "div", props: {}, children: [["Hello ", "world"]] }); @@ -54,12 +53,12 @@ describe("Hyperscript", () => { it("should create a div element with mixed array of children and comma separated children", () => { expect(v("div", null, ["Hello ", "world"], v("span", null, "Whats up"))).toEqual({ - name: "div", + tag: "div", props: {}, children: [ ["Hello ", "world"], { - name: "span", + tag: "span", props: {}, children: ["Whats up"] } @@ -69,7 +68,7 @@ describe("Hyperscript", () => { it("should create a div element with mixed nested arrays of children ", () => { expect(v("div", null, ["Hello ", "world", ["Only", ["for", "this", ["time"]]]])).toEqual({ - name: "div", + tag: "div", props: {}, children: [["Hello ", "world", ["Only", ["for", "this", ["time"]]]]] }); @@ -77,7 +76,7 @@ describe("Hyperscript", () => { it("should create a div element with props", () => { expect(v("div", { id: "unique", class: "unique" })).toEqual({ - name: "div", + tag: "div", props: { id: "unique", class: "unique" @@ -89,12 +88,12 @@ describe("Hyperscript", () => { it("should create a div element from string", () => { expect(v.trust('
Hola mundo
')).toEqual([ { - name: "div", + tag: "div", props: { id: "unique", class: "unique" }, - children: [{ nodeValue: "Hola mundo", dom: expect.anything() }], + children: [expect.objectContaining({ nodeValue: "Hola mundo", dom: expect.anything() })], dom: expect.anything() } ]); @@ -104,7 +103,7 @@ describe("Hyperscript", () => { let date = new Date(); expect(v("div", null, [null, "Hello", , 1, date, { hello: "world" }, ["Hello"]])).toEqual({ - name: "div", + tag: "div", props: {}, children: [[null, "Hello", undefined, 1, date, { hello: "world" }, ["Hello"]]] }); diff --git a/test/keyed_test.js b/test/keyed_test.js index 4eb5540..799aa7c 100644 --- a/test/keyed_test.js +++ b/test/keyed_test.js @@ -1,9 +1,8 @@ -import "../lib"; - import expect from "expect"; import nodePlugin from "../plugins/node"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); +v.use(nodePlugin); describe("Keyed lists", () => { let set = [1, 2, 3, 4, 5]; @@ -49,7 +48,7 @@ describe("Keyed lists", () => { let before = v.mount("body", component); keys = [...test.set]; - let after = v.update(); + let after = v.update(component); let afterString = getString(test.set); @@ -75,12 +74,12 @@ describe("Keyed lists", () => { let before = v.mount("body", component); useStrings = false; - let after = v.update(); + let after = v.update(component); let afterString = getString(keys); useStrings = true; - let afterUpdate = v.update(); + let afterUpdate = v.update(component); expect(before).toEqual("
    12345
"); expect(after).toEqual(afterString); @@ -103,12 +102,12 @@ describe("Keyed lists", () => { let before = v.mount("body", component); keys = [6, 7, 8, 9, , 10]; - let after = v.update(); + let after = v.update(component); let afterString = getString(keys); keys = [1, 2, 3, 4, 5]; - let afterUpdate = v.update(); + let afterUpdate = v.update(component); let afterUpdateString = getString(keys); diff --git a/test/lifecycle_test.js b/test/lifecycle_test.js index 44c434e..62cd4e6 100644 --- a/test/lifecycle_test.js +++ b/test/lifecycle_test.js @@ -1,9 +1,8 @@ -import "../lib"; - import expect from "expect"; import nodePlugin from "../plugins/node"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); +v.use(nodePlugin); describe("Lifecycle", () => { it("Mount and update", () => { @@ -19,10 +18,10 @@ describe("Lifecycle", () => { calls.push("component oncreate"); }, - onbeforeupdate() { + shouldupdate() { // before dom element is updated // if you return false the update step is skipped - calls.push("component onbeforeupdate"); + calls.push("component shouldupdate"); }, onupdate() { @@ -98,24 +97,24 @@ describe("Lifecycle", () => { let expectedLifeCycleCalls = [ "component oncreate", "oncreate", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "onremove", "onspanremove", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "oncreate", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "onupdate", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "onupdate", "onspanremove", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "onupdate", - "component onbeforeupdate", + "component shouldupdate", "component onupdate", "onremove", "onspanremove", @@ -125,17 +124,17 @@ describe("Lifecycle", () => { result.push(v.mount("body", Lifecycle)); s = 0; - result.push(v.update()); + result.push(v.update(Lifecycle)); s = 1; - result.push(v.update()); + result.push(v.update(Lifecycle)); s = 2; - result.push(v.update()); + result.push(v.update(Lifecycle)); s = 1; - result.push(v.update()); + result.push(v.update(Lifecycle)); s = 3; - result.push(v.update()); + result.push(v.update(Lifecycle)); s = 0; - result.push(v.update()); + result.push(v.update(Lifecycle)); expect(result).toEqual(expectedDom); expect(calls).toEqual(expectedLifeCycleCalls); diff --git a/test/mount_n_update_test.js b/test/mount_n_update_test.js index 6a484ac..03b4026 100644 --- a/test/mount_n_update_test.js +++ b/test/mount_n_update_test.js @@ -1,9 +1,8 @@ -import "../lib"; - import expect from "expect"; import nodePlugin from "../plugins/node"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); +v.use(nodePlugin); describe("Mount and update", () => { it("Mount and update with POJO component", () => { @@ -19,7 +18,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); Component.world = "John Doe"; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -38,7 +37,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); Component.world = "John Doe"; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -60,7 +59,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); state.world = "John Doe"; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -68,6 +67,26 @@ describe("Mount and update", () => { }); }); + it("Mount and update with Vnode Component", () => { + let Component = ({ hello }, ...children) => ( +
+ Hello World + Hello {hello} + {...children} +
+ ); + + expect( + v.mount( + "body", + + Hello John + Hello Jane + + ) + ).toEqual('
Hello WorldHello worldHello JohnHello Jane
'); + }); + it("Handle multiple update calls", () => { let Component = { world: "World", @@ -80,8 +99,8 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); Component.world = "John Doe"; - result.after = v.update(); - result.afteragain = v.update(); + result.after = v.update(Component); + result.afteragain = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -91,7 +110,7 @@ describe("Mount and update", () => { }); it("Antipattern: Mount and update with functional stateless component", () => { - let Component = (props) =>
Hello {props.world}
; + let Component = ({ props }) =>
Hello {props.world}
; let props = { world: "World", id: "example" @@ -99,9 +118,11 @@ describe("Mount and update", () => { let result = {}; - result.before = v.mount("body", Component, props); + let app = ; + + result.before = v.mount("body", app); props.world = "John Doe"; - result.after = v.update(props); + result.after = v.update(app); expect(result).toEqual({ before: '
Hello World
', @@ -117,7 +138,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); text = false; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: "Hello world", @@ -133,7 +154,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); text = true; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: "
Hello world
", @@ -149,7 +170,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); disabled = false; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: '
Hello world
', @@ -165,7 +186,7 @@ describe("Mount and update", () => { result.before = v.mount("body", Component); disabled = true; - result.after = v.update(); + result.after = v.update(Component); expect(result).toEqual({ before: "
Hello world
", @@ -191,8 +212,8 @@ describe("Mount and update", () => { }); it("should fail silently if try to update before mount", () => { - v.unMount(); - v.update(); + let Component = () =>
Hello world
; + v.update(Component); }); it("should handle text vnode as new node", () => { @@ -202,52 +223,21 @@ describe("Mount and update", () => { expect(result).toEqual("Some text"); vnode.children = ["Other text"]; - let result2 = v.update(); + let result2 = v.update(component); expect(result2).toEqual("Some text"); }); - it("should handle the passing of data with the data property", () => { - let data = { foo: "bar" }; - let onupdate = (newNode, oldNode) => expect(newNode.props.data).toEqual(oldNode.props.data); - let component = () =>
; + it("should handle the passing of state with the state property", () => { + let state = { foo: "bar" }; + let component = () =>
expect(newNode.props.state).toEqual(oldNode.props.state)} />; let result = v.mount("body", component); expect(result).toEqual("
"); - let result2 = v.update(); + let result2 = v.update(component); expect(result2).toEqual("
"); }); - it("should create another v instance using the v.newInstance method", () => { - // We create a new instance - let v2 = v.newInstance(); - - let count = 0; - let component = () => `Hello world ${count}`; - - // Get the first render - let result1 = v.mount("body", component); - let result2 = v2.mount("body", component); - - // Bot updates must be equal - expect(result1).toEqual("Hello world 0"); - expect(result2).toEqual("Hello world 0"); - - // We increment the counter and unMount the first instance - count++; - v.unMount(); - - // Get the second render - let result3 = v.update(); - let result4 = v2.update(); - - // For the first instance should be '' because component has been unMounted; - expect(result3).toEqual(""); - - // For the second instance should be 'Hello world 1' because it is still mounted - expect(result4).toEqual("Hello world 1"); - }); - it("should allow to use fragments", () => { let component = () => ( <> diff --git a/test/node_test.js b/test/node_test.js index 8e93610..3e6668c 100644 --- a/test/node_test.js +++ b/test/node_test.js @@ -1,17 +1,17 @@ -import "../lib"; +import plugin, { htmlToHyperscript, icons, inline, render, sw } from "../plugins/node"; import expect from "expect"; import fs from "fs"; -import nodePlugin from "../plugins/node"; import packageJson from "../package.json"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); +v.use(plugin); describe("Node test", () => { it("Get hyperscript string from html", () => { let html = 'Hello world'; - let dom = v.htmlToHyperscript(html); + let dom = htmlToHyperscript(html); expect(dom).toEqual(`[ v("body", {}, [ @@ -22,7 +22,7 @@ describe("Node test", () => { html = 'Hello world'; - dom = v.htmlToHyperscript(html); + dom = htmlToHyperscript(html); expect(dom).toEqual(`[ v("html", {}, [ @@ -37,7 +37,7 @@ describe("Node test", () => { html = 'Hello world'; - dom = v.htmlToHyperscript(html); + dom = htmlToHyperscript(html); expect(dom).toEqual(`[ "", @@ -53,7 +53,7 @@ describe("Node test", () => { html = 'Hello world'; - dom = v.htmlToHyperscript(html); + dom = htmlToHyperscript(html); expect(dom).toEqual(`[ v("head", {}, [ @@ -63,7 +63,7 @@ describe("Node test", () => { html = '
Hello world
'; - dom = v.htmlToHyperscript(html); + dom = htmlToHyperscript(html); expect(dom).toEqual(`[ v("div", {}, [ @@ -74,7 +74,7 @@ describe("Node test", () => { html = 'Hello world'; - dom = v.htmlToHyperscript(html); + dom = htmlToHyperscript(html); expect(dom).toEqual(`[ v("link", {"rel":"shortcult icon","href":"/icons/favicon.ico"}, []), @@ -82,9 +82,15 @@ describe("Node test", () => { ]`); }); + it("Get html from hyperscript", () => { + let Component = () =>
Hello world
; + + expect(render()).toEqual("
Hello world
"); + }); + it("Should create a service worker file", async () => { let file = ".tmp/sw.js"; - await v.sw(file, { + await sw(file, { name: "Test", version: packageJson.version, urls: ["/", "/hello"] @@ -141,7 +147,7 @@ describe("Node test", () => { } }; - await v.icons("./assets/icon.png", favicons); + await icons("./assets/icon.png", favicons); expect(fs.existsSync(".tmp/favicon.ico")).toBeTruthy(); expect(fs.existsSync(".tmp/links.js")).toBeTruthy(); expect(fs.existsSync(".tmp/manifest.json")).toBeTruthy(); @@ -153,28 +159,21 @@ describe("Node test", () => { span{display:block;} span.hello{display: inline-block} `; - - await v.inline.css({ raw: css }); - let cleanCss = await v.inline.uncss([html]); + let cleanCss = await inline.uncss([html], css); expect(cleanCss).toEqual("span{display:block}"); }); it("should inline js", async () => { - v.inline.extensions("ts"); - // await v.inline.ts("./lib/index.ts.old", { outputOptions: { minify: true } }); - await v.inline.ts("./lib/index.ts", { outputOptions: { compact: true } }); - await v.inline.js("./bench/index-old.js", { outputOptions: { compact: true } }); - console.log(v.inline.ts()[0].raw.length); - // console.log(v.inline.ts()[1].raw.length); - console.log(v.inline.js()[0].raw.length); - - // console.log(v.inline.ts()[1].raw); - // fs.writeFileSync("./dist/valyrian.lite.js", v.inline.ts()[1].raw); + let { raw: indexTs } = await inline("./lib/index.ts", { compact: true }); + let { raw: indexOld } = await inline("./bench/index-old.js", { compact: true }); + console.log(indexTs.length); + // console.log(inline.ts()[1].raw.length); + console.log(indexOld.length); - // expect(v.inline.ts()[0].raw.length).toBeLessThan(5115); + // console.log(inline.ts()[1].raw); + // fs.writeFileSync("./dist/valyrian.lite.js", inline.ts()[1].raw); - let compiled = fs.readFileSync("./dist/valyrian.min.js", "utf8"); - console.log(compiled.length); + // expect(inline.ts()[0].raw.length).toBeLessThan(5115); }); }); diff --git a/test/request_test.js b/test/request_test.js index dc0ba5e..e00d058 100644 --- a/test/request_test.js +++ b/test/request_test.js @@ -1,12 +1,10 @@ -import "../lib"; - import expect from "expect"; import fastify from "fastify"; import nodePlugin from "../plugins/node"; -import requestPlugin from "../plugins/request"; +import request from "../plugins/request"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); -v.usePlugin(requestPlugin); +v.use(nodePlugin); let posts = []; for (let i = 10; i--; ) { @@ -56,7 +54,7 @@ let createServer = async () => { describe("Request", () => { it("should get", async () => { let server = await createServer(); - let res = await v.request.get(`${server.baseUrl}/posts/1`); + let res = await request.get(`${server.baseUrl}/posts/1`); expect(res).toEqual({ userId: 1, id: 1, @@ -72,7 +70,7 @@ describe("Request", () => { it("should post", async () => { let server = await createServer(); - let res = await v.request.post( + let res = await request.post( `${server.baseUrl}/posts`, { title: "foo", @@ -96,7 +94,7 @@ describe("Request", () => { it("should put", async () => { let server = await createServer(); - let res = await v.request.put( + let res = await request.put( `${server.baseUrl}/posts/1`, { id: 1, @@ -122,7 +120,7 @@ describe("Request", () => { it("should patch", async () => { let server = await createServer(); - let res = await v.request.patch( + let res = await request.patch( `${server.baseUrl}/posts/1`, { body: "bar" @@ -144,14 +142,14 @@ describe("Request", () => { it("should delete", async () => { let server = await createServer(); - let res = await v.request.delete(`${server.baseUrl}/posts/1`); + let res = await request.delete(`${server.baseUrl}/posts/1`); expect(res).toEqual({}); await server.close(); }); it("should serialize data", async () => { let server = await createServer(); - let res = await v.request.get(`${server.baseUrl}/posts/`, { + let res = await request.get(`${server.baseUrl}/posts/`, { userId: 1 }); expect(res).toEqual(expect.any(Array)); @@ -161,7 +159,7 @@ describe("Request", () => { it("should resolve with full response", async () => { let server = await createServer(); - let res = await v.request.get(`${server.baseUrl}/posts/1`, null, { resolveWithFullResponse: true }); + let res = await request.get(`${server.baseUrl}/posts/1`, null, { resolveWithFullResponse: true }); expect(res).toEqual( expect.objectContaining({ body: expect.any(Object), @@ -176,8 +174,8 @@ describe("Request", () => { it("should create a scoped request", async () => { let server = await createServer(); - let request = v.request.new(`${server.baseUrl}`); - let res = await request.get("/posts", { + let request2 = request.new(`${server.baseUrl}`); + let res = await request2.get("/posts", { userId: 1 }); expect(res).toEqual(expect.any(Array)); @@ -187,21 +185,21 @@ describe("Request", () => { it("should create a scoped request with allowed methods", async () => { let server = await createServer(); - let request = v.request.new(`${server.baseUrl}`, { methods: ["get"] }); - let res = await request.get("/posts", { + let request2 = request.new(`${server.baseUrl}`, { methods: ["get"] }); + let res = await request2.get("/posts", { userId: 1 }); expect(res).toEqual(expect.any(Array)); expect(res.length).toEqual(10); - expect(request.post).toBeUndefined(); + expect(request2.post).toBeUndefined(); await server.close(); }); it("should create a child scoped request", async () => { let server = await createServer(); - let request = v.request.new(`${server.baseUrl}/`); - let requestChild = request.new("/posts"); + let request2 = request.new(`${server.baseUrl}/`); + let requestChild = request2.new("/posts"); let res = await requestChild.get("/", { userId: 1 }); @@ -212,8 +210,8 @@ describe("Request", () => { it("should create a child scoped request with allowed methods", async () => { let server = await createServer(); - let request = v.request.new(`${server.baseUrl}/`, { methods: ["get"] }); - let requestChild = request.new("/posts"); + let request2 = request.new(`${server.baseUrl}/`, { methods: ["get"] }); + let requestChild = request2.new("/posts"); let res = await requestChild.get("/", { userId: 1 }); @@ -226,9 +224,9 @@ describe("Request", () => { it("should work with server side rendering of local requests", async () => { let server = await createServer(); - v.request.options("urls.node", `${server.baseUrl}`); + request.options("urls.node", `${server.baseUrl}`); - let res = await v.request.get("/hello", null, { headers: { Accept: "text/html" } }); + let res = await request.get("/hello", null, { headers: { Accept: "text/html" } }); expect(res).toEqual("Hello world"); @@ -237,10 +235,10 @@ describe("Request", () => { it("should work with server side rendering of api requests", async () => { let server = await createServer(); - v.request.options("urls.node", `${server.baseUrl}`); - v.request.options("urls.api", "http://example.com/api"); + request.options("urls.node", `${server.baseUrl}`); + request.options("urls.api", "http://example.com/api"); - let res = await v.request.get("http://example.com/api/hello", null, { headers: { Accept: "text/html" } }); + let res = await request.get("http://example.com/api/hello", null, { headers: { Accept: "text/html" } }); expect(res).toEqual("Hello world"); @@ -249,13 +247,13 @@ describe("Request", () => { it("should work with server side rendering of local requests with scoped request", async () => { let server = await createServer(); - let request = v.request.new("/", { + let request2 = request.new("/", { urls: { node: `${server.baseUrl}` } }); - let res = await request.get("/hello", null, { headers: { Accept: "text/html" } }); + let res = await request2.get("/hello", null, { headers: { Accept: "text/html" } }); expect(res).toEqual("Hello world"); @@ -264,14 +262,14 @@ describe("Request", () => { it("should work with server side rendering of api requests with scoped request", async () => { let server = await createServer(); - let request = v.request.new("/", { + let request2 = request.new("/", { urls: { node: `${server.baseUrl}`, api: "http://example.com/api" } }); - let res = await request.get("http://example.com/api/hello", null, { headers: { Accept: "text/html" } }); + let res = await request2.get("http://example.com/api/hello", null, { headers: { Accept: "text/html" } }); expect(res).toEqual("Hello world"); @@ -280,14 +278,14 @@ describe("Request", () => { it("should work with server side rendering of local requests with child scoped request", async () => { let server = await createServer(); - let request = v.request.new("/", { + let request2 = request.new("/", { urls: { node: `${server.baseUrl}` }, methods: ["get"] }); - let childRequest = request.new("/hello"); + let childRequest = request2.new("/hello"); let res = await childRequest.get("/", null, { headers: { Accept: "text/html" } }); @@ -300,7 +298,7 @@ describe("Request", () => { it("should work with server side rendering of api requests with child scoped request", async () => { let server = await createServer(); - let request = v.request.new("/", { + let request2 = request.new("/", { urls: { node: `${server.baseUrl}`, api: "http://example.com/api" @@ -308,7 +306,7 @@ describe("Request", () => { methods: ["get"] }); - let childRequest = request.new("http://example.com/api/hello"); + let childRequest = request2.new("http://example.com/api/hello"); let res = await childRequest.get("/", null, { headers: { Accept: "text/html" } }); diff --git a/test/router_test.js b/test/router_test.js index c1cf805..ecd44d8 100644 --- a/test/router_test.js +++ b/test/router_test.js @@ -1,17 +1,17 @@ -import "../lib"; +import plugin, { Router } from "../plugins/router"; import expect from "expect"; import nodePlugin from "../plugins/node"; -import router from "../plugins/router"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); -v.usePlugin(router); +v.use(plugin); +v.use(nodePlugin); // eslint-disable-next-line max-lines-per-function describe("Router", () => { it("Dev test", async () => { let Component = () =>
Hello world
; - let router = v.Router(); + let router = new Router(); router .get( "/", @@ -30,7 +30,7 @@ describe("Router", () => { ) .get("/hello/:world", [() => console.log("Hello 7"), () => Component], () => console.log("Hello 7")); - let subrouter = v.Router(); + let subrouter = new Router(); subrouter .get( @@ -54,9 +54,9 @@ describe("Router", () => { router.use("/ok", subrouter); router.use(() => () => "Not found"); - v.routes("body", router); - expect(await v.routes.go("/ok/not/found/url?hello=world")).toEqual("Not ok"); - expect(await v.routes.go("/not/found/url?hello=world")).toEqual("Not found"); + v.mount("body", router); + expect(await router.go("/ok/not/found/url?hello=world")).toEqual("Not ok"); + expect(await router.go("/not/found/url?hello=world")).toEqual("Not found"); }); it("Mount and update with POJO component", async () => { @@ -69,15 +69,15 @@ describe("Router", () => { }; let result = {}; - let router = v.Router(); + let router = new Router(); router.get("/", () => Component); - v.routes("body", router); + v.mount("body", router); - result.before = await v.routes.go("/"); + result.before = await router.go("/"); Component.world = "John Doe"; - result.after = await v.routes.go("/"); + result.after = await router.go("/"); Component.world = "World"; - result.final = v.update(); + result.final = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -95,15 +95,15 @@ describe("Router", () => { Component.id = "example"; let result = {}; - let router = v.Router(); + let router = new Router(); router.get("/", () => Component); - v.routes("body", router); + v.mount("body", router); - result.before = await v.routes.go("/"); + result.before = await router.go("/"); Component.world = "John Doe"; - result.after = await v.routes.go("/"); + result.after = await router.go("/"); Component.world = "World"; - result.final = v.update(); + result.final = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -123,15 +123,15 @@ describe("Router", () => { }; let result = {}; - let router = v.Router(); + let router = new Router(); router.get("/", () => Component); - v.routes("body", router); + v.mount("body", router); - result.before = await v.routes.go("/"); + result.before = await router.go("/"); state.world = "John Doe"; - result.after = await v.routes.go("/"); + result.after = await router.go("/"); state.world = "World"; - result.final = v.update(); + result.final = v.update(Component); expect(result).toEqual({ before: '
Hello World
', @@ -148,15 +148,15 @@ describe("Router", () => { }; let result = {}; - let router = v.Router(); - router.get("/", () => Component); - v.routes("body", router); + let router = new Router(); + router.get("/", () => ); + v.mount("body", router); - result.before = await v.routes.go("/", props); + result.before = await router.go("/"); props.world = "John Doe"; - result.after = await v.routes.go("/", props); + result.after = await router.go("/"); props.world = "World"; - result.final = v.update(props); + result.final = await router.go("/"); expect(result).toEqual({ before: '
Hello World
', @@ -169,15 +169,15 @@ describe("Router", () => { let Hello = () => "Hello world"; let NotFound = () =>
Ups, no route was found.
; - let router = v.Router(); + let router = new Router(); router.get("/", () => Hello); router.use(() => NotFound); - v.routes("body", router); + v.mount("body", router); let result = {}; - result.found = await v.routes.go("/"); - result.notFound = await v.routes.go("/not_found"); + result.found = await router.go("/"); + result.notFound = await router.go("/not_found"); expect(result).toEqual({ found: "Hello world", @@ -198,7 +198,7 @@ describe("Router", () => { ); }; - let router = v.Router(); + let router = new Router(); router.get( "/hello", () => Object.assign(Hello, Store), @@ -206,11 +206,11 @@ describe("Router", () => { ); router.get("/hello/:world/whats/:up", [({ params }) => Object.assign(Hello, params), () => Hello]); - v.routes("body", router); + v.mount("body", router); let result = {}; - result.before = await v.routes.go("/hello"); - result.after = await v.routes.go("/hello/Mike/whats/new"); + result.before = await router.go("/hello"); + result.after = await router.go("/hello/Mike/whats/new"); expect(result).toEqual({ before: "
Hello world, what's up
", @@ -222,7 +222,7 @@ describe("Router", () => { let Hello = () =>
Hello World
; let middlewares = []; - let router = v.Router(); + let router = new Router(); router.get( "/", () => middlewares.push("Middleware 1"), @@ -240,9 +240,9 @@ describe("Router", () => { // This is the final response () => Hello ); - v.routes("body", router); + v.mount("body", router); - let result = await v.routes.go("/"); + let result = await router.go("/"); expect(result).toEqual("
Hello World
"); expect(middlewares).toEqual([ @@ -266,7 +266,7 @@ describe("Router", () => { ); }; - let subrouter = v.Router(); + let subrouter = new Router(); subrouter .get("/from/:country", ({ params }) => { Component.world = params.world; @@ -279,13 +279,13 @@ describe("Router", () => { return Component; }); - let router = v.Router(); + let router = new Router(); router.use("/hello/:world", subrouter); - v.routes("body", router); + v.mount("body", router); let result = {}; - result.before = await v.routes.go("/hello/Mike"); - result.after = await v.routes.go("/hello/John/from/Mexico"); + result.before = await router.go("/hello/Mike"); + result.after = await router.go("/hello/John/from/Mexico"); expect(result).toEqual({ before: "
Hello Mike, from USA
", @@ -302,11 +302,11 @@ describe("Router", () => { ); - let router = v.Router(); + let router = new Router(); router.get("/", () => Component); - v.routes("body", router); + v.mount("body", router); - let result = await v.routes.go(ParentComponent, "/"); + let result = await router.go("/", ParentComponent); expect(result).toEqual("
Hello World
"); }); @@ -314,30 +314,30 @@ describe("Router", () => { it("Test show error when calling with a non url", async () => { let Component = () =>
Hello World
; - let router = v.Router(); + let router = new Router(); router.get("/", () => Component); - v.routes("body", router); + v.mount("body", router); let err; try { - await v.routes.go(null); + await router.go(null); } catch (error) { err = error.message; } - expect(err).toEqual("v.router.url.required"); + expect(err).toEqual("router.url.required"); }); it("Test show error when no component is returned", async () => { - let router = v.Router(); + let router = new Router(); router.get("/", () => { // Component is not returned }); - v.routes("body", router); + v.mount("body", router); let err; try { - await v.routes.go("/"); + await router.go("/"); } catch (error) { err = error.message; } @@ -347,14 +347,14 @@ describe("Router", () => { it("Test get routes", () => { let Component = () => "Hello world"; - let subrouter = v.Router(); + let subrouter = new Router(); subrouter.get("/from/:country", () => Component).get("/", () => Component); - let router = v.Router(); + let router = new Router(); router.use("/hello/:world", subrouter).get("/", () => Component); - v.routes("body", router); + v.mount("body", router); - expect(v.routes.get()).toEqual(["/hello/:world/from/:country", "/hello/:world", "/"]); + expect(router.routes()).toEqual(["/hello/:world/from/:country", "/hello/:world", "/"]); }); }); diff --git a/test/signals_test.js b/test/signals_test.js index 4cb164f..91a3f06 100644 --- a/test/signals_test.js +++ b/test/signals_test.js @@ -1,16 +1,14 @@ -import "../lib"; - +import Signal from "../plugins/signals"; import expect from "expect"; import nodePlugin from "../plugins/node"; -import signalsPlugin from "../plugins/signals"; +import { v } from "../lib/index"; -v.usePlugin(nodePlugin); -v.usePlugin(signalsPlugin); +v.use(nodePlugin); describe("Signals", () => { it("should create a signal", async () => { // Create signal - let counter = v.Signal(0); + let counter = Signal(0); // Read value counter(); @@ -34,7 +32,7 @@ describe("Signals", () => { let computed = counter((val) => "hello " + val); // Unlinked Pure computed - let unlinked = v.Signal(() => "hello " + counter.value); + let unlinked = Signal(() => "hello " + counter.value); let interval = setInterval(() => (counter.value += 1), 1000); expect(counter.hello).toEqual("hello 0"); @@ -62,8 +60,8 @@ describe("Signals", () => { }); it("should test effect cleanup", async () => { - let delay = v.Signal(1000); - let count = v.Signal(0); + let delay = Signal(1000); + let count = Signal(0); let effectInterval = delay((delay) => { let interval = setInterval(() => { count.value = count.value + 1; @@ -87,7 +85,7 @@ describe("Signals", () => { }); it("should test deep state effect cleanup", async () => { - let state = v.Signal({ + let state = Signal({ count: 0, delay: 1000 }); @@ -115,25 +113,26 @@ describe("Signals", () => { describe("Hooks like pattern", () => { it("should create a simple counter", async () => { let Counter = (ms) => { - let count = v.Signal(0); + let count = Signal(0); let interval = setInterval(() => { count.value = count.value + 1; }, ms); return () =>
clearInterval(interval)}>{count.value}
; }; - let result = v.mount("div", Counter(1000)); + let Component = Counter(1000); + + let result = v.mount("div", Component); expect(result).toEqual("
0
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Component); expect(result).toEqual("
2
"); - v.unMount(); }); it("should create a counter with delay change", async () => { let Counter = (ms) => { - let delay = v.Signal(ms); - let count = v.Signal(0); + let delay = Signal(ms); + let count = Signal(0); let interval = delay((delay) => { let interval = setInterval(() => { count.value = count.value + 1; @@ -143,17 +142,18 @@ describe("Hooks like pattern", () => { return () =>
{count.value}
; }; - let result = v.mount("div", Counter(1000)); + let Component = Counter(1000); + + let result = v.mount("div", Component); expect(result).toEqual("
0
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Component); expect(result).toEqual("
2
"); - v.unMount(); }); it("should create a counter with deep state", async () => { let Counter = (ms) => { - let state = v.Signal({ + let state = Signal({ count: 0, delay: ms }); @@ -166,11 +166,12 @@ describe("Hooks like pattern", () => { return () =>
{state.value.count}
; }; - let result = v.mount("div", Counter(1000)); + let Component = Counter(1000); + + let result = v.mount("div", Component); expect(result).toEqual("
0
"); await new Promise((resolve) => setTimeout(() => resolve(), 2050)); - result = v.update(); + result = v.update(Component); expect(result).toEqual("
2
"); - v.unMount(); }); }); diff --git a/test/store_test.js b/test/store_test.js index 3f0036c..5adf936 100644 --- a/test/store_test.js +++ b/test/store_test.js @@ -1,9 +1,10 @@ -import "../lib"; +import plugin, {Store} from "../plugins/store"; -import StorePlugin from "../plugins/store"; import expect from "expect"; +import { v } from "../lib/index"; + +v.use(plugin); -v.usePlugin(StorePlugin); function getNewStore() { let mainModule = { @@ -45,18 +46,18 @@ function getNewStore() { } }; - return new v.Store(mainModule); + return new Store(mainModule); } // eslint-disable-next-line max-lines-per-function describe("Store slim", () => { it("Create empty state if state is not passed", () => { - let store = new v.Store(); + let store = new Store(); expect(store.state).toBeDefined(); }); it("Use deepFrozen to froze the state", () => { - let store = new v.Store({ + let store = new Store({ state: { a: { b: { @@ -149,8 +150,8 @@ describe("Store slim", () => { } }; - const store1 = new v.Store(myModule); - const store2 = new v.Store(myModule); + const store1 = new Store(myModule); + const store2 = new Store(myModule); store1.commit("increment", 5); store2.commit("increment", 3); diff --git a/tsconfig.json b/tsconfig.json index 9518268..229dafb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,10 @@ "inlineSourceMap": true, "allowJs": false, "resolveJsonModule": true, - "removeComments": true + "removeComments": false, + "jsx": "react", + "jsxFragmentFactory": "v.fragment", + "jsxFactory": "v" }, "include": ["./lib", "./plugins"], "exclude": ["test*/**/*", "**/*.test.ts", "**/*.spec.ts"] diff --git a/yarn.lock b/yarn.lock index a2d1b60..d8f888a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,230 +2,249 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" - integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: - "@babel/highlight" "^7.16.0" + "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.16.0": - version "7.16.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" - integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== +"@babel/compat-data@^7.16.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== "@babel/core@^7.7.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.5.tgz#924aa9e1ae56e1e55f7184c8bf073a50d8677f5c" - integrity sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/generator" "^7.16.5" - "@babel/helper-compilation-targets" "^7.16.3" - "@babel/helper-module-transforms" "^7.16.5" - "@babel/helpers" "^7.16.5" - "@babel/parser" "^7.16.5" - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.5" - "@babel/types" "^7.16.0" + version "7.17.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.4.tgz#a22f1ae8999122873b3d18865e98c7a3936b8c8b" + integrity sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.3" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" -"@babel/generator@^7.16.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.5.tgz#26e1192eb8f78e0a3acaf3eede3c6fc96d22bedf" - integrity sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA== +"@babel/generator@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" + integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-compilation-targets@^7.16.3": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" - integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA== +"@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== dependencies: - "@babel/compat-data" "^7.16.0" - "@babel/helper-validator-option" "^7.14.5" + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-environment-visitor@^7.16.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz#f6a7f38b3c6d8b07c88faea083c46c09ef5451b8" - integrity sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg== +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" - integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog== +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== dependencies: - "@babel/helper-get-function-arity" "^7.16.0" - "@babel/template" "^7.16.0" - "@babel/types" "^7.16.0" + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" -"@babel/helper-get-function-arity@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" - integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ== +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" - integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg== +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-module-imports@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" - integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg== +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.16.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz#530ebf6ea87b500f60840578515adda2af470a29" - integrity sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ== +"@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== dependencies: - "@babel/helper-environment-visitor" "^7.16.5" - "@babel/helper-module-imports" "^7.16.0" - "@babel/helper-simple-access" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - "@babel/helper-validator-identifier" "^7.15.7" - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.5" - "@babel/types" "^7.16.0" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" -"@babel/helper-simple-access@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" - integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw== +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-split-export-declaration@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" - integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw== +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.16.7" -"@babel/helper-validator-identifier@^7.15.7": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helpers@^7.16.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.5.tgz#29a052d4b827846dd76ece16f565b9634c554ebd" - integrity sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw== +"@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== dependencies: - "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.5" - "@babel/types" "^7.16.0" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" -"@babel/highlight@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" - integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g== +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== dependencies: - "@babel/helper-validator-identifier" "^7.15.7" + "@babel/helper-validator-identifier" "^7.16.7" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.0", "@babel/parser@^7.16.5": - version "7.16.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.6.tgz#8f194828193e8fa79166f34a4b4e52f3e769a314" - integrity sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ== +"@babel/parser@^7.16.7", "@babel/parser@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" + integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== "@babel/runtime@^7.7.2": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" - integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" - integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/parser" "^7.16.0" - "@babel/types" "^7.16.0" - -"@babel/traverse@^7.16.5": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.5.tgz#d7d400a8229c714a59b87624fc67b0f1fbd4b2b3" - integrity sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ== - dependencies: - "@babel/code-frame" "^7.16.0" - "@babel/generator" "^7.16.5" - "@babel/helper-environment-visitor" "^7.16.5" - "@babel/helper-function-name" "^7.16.0" - "@babel/helper-hoist-variables" "^7.16.0" - "@babel/helper-split-export-declaration" "^7.16.0" - "@babel/parser" "^7.16.5" - "@babel/types" "^7.16.0" +"@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.16.7", "@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" - integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== +"@babel/types@^7.16.7", "@babel/types@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== dependencies: - "@babel/helper-validator-identifier" "^7.15.7" + "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@commitlint/execute-rule@^15.0.0": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-15.0.0.tgz#6bff7962df38e89ff9fdbc00abd79b8849c7e9f9" - integrity sha512-pyE4ApxjbWhb1TXz5vRiGwI2ssdMMgZbaaheZq1/7WC0xRnqnIhE1yUC1D2q20qPtvkZPstTYvMiRVtF+DvjUg== +"@commitlint/config-validator@^16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-16.2.1.tgz#794e769afd4756e4cf1bfd823b6612932e39c56d" + integrity sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw== + dependencies: + "@commitlint/types" "^16.2.1" + ajv "^6.12.6" + +"@commitlint/execute-rule@^16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz#60be73be4b9af97a41546e7ce59fdd33787c65f8" + integrity sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g== "@commitlint/load@>6.1.1": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-15.0.0.tgz#5bd391c1387aafe92b54cf2a86b76a5228fcf4ef" - integrity sha512-Ak1YPeOhvxmY3ioe0o6m1yLGvUAYb4BdfGgShU8jiTCmU3Mnmms0Xh/kfQz8AybhezCC3AmVTyBLaBZxOHR8kg== - dependencies: - "@commitlint/execute-rule" "^15.0.0" - "@commitlint/resolve-extends" "^15.0.0" - "@commitlint/types" "^15.0.0" - "@endemolshinegroup/cosmiconfig-typescript-loader" "^3.0.2" + version "16.2.1" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-16.2.1.tgz#301bda1bff66b3e40a85819f854eda72538d8e24" + integrity sha512-oSpz0jTyVI/A1AIImxJINTLDOMB8YF7lWGm+Jg5wVWM0r7ucpuhyViVvpSRTgvL0z09oIxlctyFGWUQQpI42uw== + dependencies: + "@commitlint/config-validator" "^16.2.1" + "@commitlint/execute-rule" "^16.2.1" + "@commitlint/resolve-extends" "^16.2.1" + "@commitlint/types" "^16.2.1" + "@types/node" ">=12" chalk "^4.0.0" cosmiconfig "^7.0.0" + cosmiconfig-typescript-loader "^1.0.0" lodash "^4.17.19" resolve-from "^5.0.0" typescript "^4.4.3" -"@commitlint/resolve-extends@^15.0.0": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-15.0.0.tgz#baf21227e2ac52cef546ec35dd6732e9b0b6e57c" - integrity sha512-7apfRJjgJsKja7lHsPfEFixKjA/fk/UeD3owkOw1174yYu4u8xBDLSeU3IinGPdMuF9m245eX8wo7vLUy+EBSg== +"@commitlint/resolve-extends@^16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz#2f7833a5a3a7aa79f508e59fcb0f1d33c45ed360" + integrity sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg== dependencies: + "@commitlint/config-validator" "^16.2.1" + "@commitlint/types" "^16.2.1" import-fresh "^3.0.0" lodash "^4.17.19" resolve-from "^5.0.0" resolve-global "^1.0.0" -"@commitlint/types@^15.0.0": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-15.0.0.tgz#46fa7bda3e6340caf3e3a2e415bcb78ff0195eed" - integrity sha512-OMSLX+QJnyNoTwws54ULv9sOvuw9GdVezln76oyUd4YbMMJyaav62aSXDuCdWyL2sm9hTkSzyEi52PNaIj/vqw== +"@commitlint/types@^16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-16.2.1.tgz#f25d373b88b01e51fc3fa44488101361945a61bd" + integrity sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA== dependencies: chalk "^4.0.0" @@ -253,24 +272,14 @@ dependencies: "@cspotcode/source-map-consumer" "0.8.0" -"@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" - integrity sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA== - dependencies: - lodash.get "^4" - make-error "^1" - ts-node "^9" - tslib "^2" - -"@eslint/eslintrc@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318" - integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== +"@eslint/eslintrc@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3" + integrity sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.2.0" + espree "^9.3.1" globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" @@ -286,9 +295,9 @@ ajv "^6.12.6" "@humanwhocodes/config-array@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" - integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== + version "0.9.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.3.tgz#f2564c744b387775b436418491f15fce6601f63e" + integrity sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -325,10 +334,10 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/types@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" - integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -626,6 +635,24 @@ "@babel/runtime" "^7.7.2" regenerator-runtime "^0.13.3" +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@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" @@ -720,15 +747,15 @@ once "^1.4.0" "@octokit/request@^5.6.0": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.2.tgz#1aa74d5da7b9e04ac60ef232edd9a7438dcf32d8" - integrity sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA== + version "5.6.3" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0" + integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A== dependencies: "@octokit/endpoint" "^6.0.1" "@octokit/request-error" "^2.1.0" "@octokit/types" "^6.16.1" is-plain-object "^5.0.0" - node-fetch "^2.6.1" + node-fetch "^2.6.7" universal-user-agent "^6.0.0" "@octokit/rest@18.12.0": @@ -748,13 +775,13 @@ dependencies: "@octokit/openapi-types" "^11.2.0" -"@release-it/conventional-changelog@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@release-it/conventional-changelog/-/conventional-changelog-3.3.0.tgz#0f79e4b736412040d37c2b84bf433e393268c08e" - integrity sha512-pchCHf+wNpn15oj2hau4gisFKQat/01JuTzAwlGsQE83ZUBknU4dRlPA3xf5F5f3K70VVTQ3lx4/lgQvR+zxww== +"@release-it/conventional-changelog@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@release-it/conventional-changelog/-/conventional-changelog-4.1.0.tgz#86a91259c331c081f49ca915847102da6e454942" + integrity sha512-MTinrJNyzhaqJ71gg4dZCe+wzdtssUjweQT7p1lDtSqRP6BtGp98NlfBlXACnCaOaETb7bI3fknoLsztqibTpQ== dependencies: concat-stream "^2.0.0" - conventional-changelog "^3.1.24" + conventional-changelog "^3.1.25" conventional-recommended-bump "^6.1.0" prepend-file "^2.0.0" @@ -764,9 +791,9 @@ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@sindresorhus/is@^4.0.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.2.0.tgz#667bfc6186ae7c9e0b45a08960c551437176e1ca" - integrity sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw== + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.4.0.tgz#e277e5bdbdf7cb1e20d320f02f5e2ed113cd3185" + integrity sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ== "@szmarczak/http-timer@^1.1.2": version "1.1.2" @@ -847,9 +874,9 @@ integrity sha512-a3xgqnFTuNJDm1fjsTjHocYJ40Cz3t8utYpi5GNaxzrJC2HSD08ym+whIL7fNqiqBCdM9bcqD1H/tORWAFXoZw== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": version "3.0.0" @@ -899,15 +926,10 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*", "@types/node@^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.0.tgz#62797cee3b8b497f6547503b2312254d4fe3c2bb" - integrity sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw== - -"@types/node@^16.0.0": - version "16.11.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.14.tgz#4939fb42e5b0ffb3ea7e193c28244fe7414977a6" - integrity sha512-mK6BKLpL0bG6v2CxHbm0ed6RcZrAtTHBTd/ZpnlVPVa3HkumsqLE4BC4u6TQ8D7pnrRbOU0am6epuALs+Ncnzw== +"@types/node@*", "@types/node@>=12", "@types/node@^17.0.0", "@types/node@^17.0.18": + version "17.0.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.18.tgz#3b4fed5cfb58010e3a2be4b6e74615e4847f1074" + integrity sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -958,13 +980,14 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.7.0.tgz#12d54709f8ea1da99a01d8a992cd0474ad0f0aa9" - integrity sha512-8RTGBpNn5a9M628wBPrCbJ+v3YTEOE2qeZb7TDkGKTDXSj36KGRg92SpFFaR/0S3rSXQxM0Og/kV9EyadsYSBg== +"@typescript-eslint/eslint-plugin@^5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.12.0.tgz#bb46dd7ce7015c0928b98af1e602118e97df6c70" + integrity sha512-fwCMkDimwHVeIOKeBHiZhRUfJXU8n6xW1FL9diDxAyGAFvKcH4csy0v7twivOQdQdA0KC8TDr7GGRd3L4Lv0rQ== dependencies: - "@typescript-eslint/experimental-utils" "5.7.0" - "@typescript-eslint/scope-manager" "5.7.0" + "@typescript-eslint/scope-manager" "5.12.0" + "@typescript-eslint/type-utils" "5.12.0" + "@typescript-eslint/utils" "5.12.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -972,60 +995,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.7.0.tgz#2b1633e6613c3238036156f70c32634843ad034f" - integrity sha512-u57eZ5FbEpzN5kSjmVrSesovWslH2ZyNPnaXQMXWgH57d5+EVHEt76W75vVuI9qKZ5BMDKNfRN+pxcPEjQjb2A== +"@typescript-eslint/parser@^5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.12.0.tgz#0ca669861813df99ce54916f66f524c625ed2434" + integrity sha512-MfSwg9JMBojMUoGjUmX+D2stoQj1CBYTCP0qnnVtu9A+YQXVKNtLjasYh+jozOcrb/wau8TCfWOkQTiOAruBog== dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.7.0" - "@typescript-eslint/types" "5.7.0" - "@typescript-eslint/typescript-estree" "5.7.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" + "@typescript-eslint/scope-manager" "5.12.0" + "@typescript-eslint/types" "5.12.0" + "@typescript-eslint/typescript-estree" "5.12.0" + debug "^4.3.2" -"@typescript-eslint/parser@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.7.0.tgz#4dca6de463d86f02d252e681136a67888ea3b181" - integrity sha512-m/gWCCcS4jXw6vkrPQ1BjZ1vomP01PArgzvauBqzsoZ3urLbsRChexB8/YV8z9HwE3qlJM35FxfKZ1nfP/4x8g== +"@typescript-eslint/scope-manager@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.12.0.tgz#59619e6e5e2b1ce6cb3948b56014d3a24da83f5e" + integrity sha512-GAMobtIJI8FGf1sLlUWNUm2IOkIjvn7laFWyRx7CLrv6nLBI7su+B7lbStqVlK5NdLvHRFiJo2HhiDF7Ki01WQ== dependencies: - "@typescript-eslint/scope-manager" "5.7.0" - "@typescript-eslint/types" "5.7.0" - "@typescript-eslint/typescript-estree" "5.7.0" - debug "^4.3.2" + "@typescript-eslint/types" "5.12.0" + "@typescript-eslint/visitor-keys" "5.12.0" -"@typescript-eslint/scope-manager@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.7.0.tgz#70adf960e5a58994ad50438ba60d98ecadd79452" - integrity sha512-7mxR520DGq5F7sSSgM0HSSMJ+TFUymOeFRMfUfGFAVBv8BR+Jv1vHgAouYUvWRZeszVBJlLcc9fDdktxb5kmxA== +"@typescript-eslint/type-utils@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.12.0.tgz#aaf45765de71c6d9707c66ccff76ec2b9aa31bb6" + integrity sha512-9j9rli3zEBV+ae7rlbBOotJcI6zfc6SHFMdKI9M3Nc0sy458LJ79Os+TPWeBBL96J9/e36rdJOfCuyRSgFAA0Q== dependencies: - "@typescript-eslint/types" "5.7.0" - "@typescript-eslint/visitor-keys" "5.7.0" + "@typescript-eslint/utils" "5.12.0" + debug "^4.3.2" + tsutils "^3.21.0" -"@typescript-eslint/types@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.7.0.tgz#2d4cae0105ba7d08bffa69698197a762483ebcbe" - integrity sha512-5AeYIF5p2kAneIpnLFve8g50VyAjq7udM7ApZZ9JYjdPjkz0LvODfuSHIDUVnIuUoxafoWzpFyU7Sqbxgi79mA== +"@typescript-eslint/types@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.12.0.tgz#5b4030a28222ee01e851836562c07769eecda0b8" + integrity sha512-JowqbwPf93nvf8fZn5XrPGFBdIK8+yx5UEGs2QFAYFI8IWYfrzz+6zqlurGr2ctShMaJxqwsqmra3WXWjH1nRQ== -"@typescript-eslint/typescript-estree@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.7.0.tgz#968fad899050ccce4f08a40cd5fabc0798525006" - integrity sha512-aO1Ql+izMrTnPj5aFFlEJkpD4jRqC4Gwhygu2oHK2wfVQpmOPbyDSveJ+r/NQo+PWV43M6uEAeLVbTi09dFLhg== +"@typescript-eslint/typescript-estree@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.0.tgz#cabf545fd592722f0e2b4104711e63bf89525cd2" + integrity sha512-Dd9gVeOqt38QHR0BEA8oRaT65WYqPYbIc5tRFQPkfLquVEFPD1HAtbZT98TLBkEcCkvwDYOAvuSvAD9DnQhMfQ== dependencies: - "@typescript-eslint/types" "5.7.0" - "@typescript-eslint/visitor-keys" "5.7.0" + "@typescript-eslint/types" "5.12.0" + "@typescript-eslint/visitor-keys" "5.12.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.7.0.tgz#e05164239eb7cb8aa9fa06c516ede480ce260178" - integrity sha512-hdohahZ4lTFcglZSJ3DGdzxQHBSxsLVqHzkiOmKi7xVAWC4y2c1bIMKmPJSrA4aOEoRUPOKQ87Y/taC7yVHpFg== +"@typescript-eslint/utils@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.12.0.tgz#92fd3193191621ab863add2f553a7b38b65646af" + integrity sha512-k4J2WovnMPGI4PzKgDtQdNrCnmBHpMUFy21qjX2CoPdoBcSBIMvVBr9P2YDP8jOqZOeK3ThOL6VO/sy6jtnvzw== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.12.0" + "@typescript-eslint/types" "5.12.0" + "@typescript-eslint/typescript-estree" "5.12.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.12.0": + version "5.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.0.tgz#1ac9352ed140b07ba144ebf371b743fdf537ec16" + integrity sha512-cFwTlgnMV6TgezQynx2c/4/tx9Tufbuo9LPzmWqyRC3QC4qTGkAG1C6pBr0/4I10PAI/FlYunI3vJjIcu+ZHMg== dependencies: - "@typescript-eslint/types" "5.7.0" + "@typescript-eslint/types" "5.12.0" eslint-visitor-keys "^3.0.0" "@ungap/promise-all-settled@1.1.2": @@ -1041,18 +1073,23 @@ JSONStream@^1.0.4: jsonparse "^1.2.0" through ">=2.2.7 <3" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + abstract-logging@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== accepts@~1.3.5: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-jsx@^5.3.1: version "5.3.2" @@ -1064,10 +1101,10 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.4.1, acorn@^8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== +acorn@^8.4.1, acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== add-stream@^1.0.0: version "1.0.0" @@ -1093,9 +1130,9 @@ ajv@^6.10.0, ajv@^6.11.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: uri-js "^4.2.2" ajv@^8.1.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" - integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1109,7 +1146,7 @@ ansi-align@^3.0.0: dependencies: string-width "^4.1.0" -ansi-colors@4.1.1, ansi-colors@^4.1.1: +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== @@ -1126,31 +1163,11 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: +ansi-regex@^2.0.0, ansi-regex@^3.0.0, ansi-regex@^4.1.0, ansi-regex@^5.0.1, ansi-regex@^6.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-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1540,14 +1557,14 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.0.0, camelcase@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" - integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001286: - version "1.0.30001287" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001287.tgz#5fab6a46ab9e47146d5dd35abfe47beaf8073c71" - integrity sha512-4udbs9bc0hfNrcje++AxBuc6PfLNHwh3PO9kbwnfCQWyqtlzg3py0YgFu8jyRTTo85VAz4U+VLxSlID09vNtWA== + version "1.0.30001312" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" + integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== caseless@~0.12.0: version "0.12.0" @@ -1581,10 +1598,10 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@3.5.2, chokidar@^3.0.0: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== +chokidar@3.5.3, chokidar@^3.0.0, chokidar@^3.5.2: + 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" @@ -1602,11 +1619,9 @@ chownr@^1.1.1: integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chroma-js@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.2.tgz#1075cb9ae25bcb2017c109394168b5cf3aa500ec" - integrity sha512-ri/ouYDWuxfus3UcaMxC1Tfp3IE9K5iQzxc2hSxbBRVNQFut1UuGAsZmiAf2mOUubzGJwgMSv9lHg+XqLaz1QQ== - dependencies: - cross-env "^6.0.3" + version "2.4.2" + resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.4.2.tgz#dffc214ed0c11fa8eefca2c36651d8e57cbfb2b0" + integrity sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A== ci-info@^2.0.0: version "2.0.0" @@ -1618,10 +1633,10 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== -clean-css@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.2.tgz#d3a7c6ee2511011e051719838bdcf8314dc4548d" - integrity sha512-/eR8ru5zyxKzpBLv9YZvMXgTSSQn7AdkMItMYynsFgGwTveCRVam9IUPFloE85B4vAIj05IuKmmEoV7/AQjT0w== +clean-css@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.4.tgz#982b058f8581adb2ae062520808fb2429bd487a4" + integrity sha512-nKseG8wCzEuji/4yrgM/5cthL9oTDc5UOQyFMvW/Q53oP6gLH690o1NbuTh6Y18nujr7BxlsFuS7gXLnLzKJGg== dependencies: source-map "~0.6.0" @@ -1893,9 +1908,9 @@ conventional-changelog-codemirror@^2.0.8: q "^1.5.1" conventional-changelog-conventionalcommits@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz#f4c0921937050674e578dc7875f908351ccf4014" - integrity sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw== + version "4.6.3" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz#0765490f56424b46f6cb4db9135902d6e5a36dc2" + integrity sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g== dependencies: compare-func "^2.0.0" lodash "^4.17.15" @@ -1963,13 +1978,13 @@ conventional-changelog-preset-loader@^2.3.4: integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== conventional-changelog-writer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz#c4042f3f1542f2f41d7d2e0d6cad23aba8df8eec" - integrity sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g== + version "5.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359" + integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ== dependencies: conventional-commits-filter "^2.0.7" dateformat "^3.0.0" - handlebars "^4.7.6" + handlebars "^4.7.7" json-stringify-safe "^5.0.1" lodash "^4.17.15" meow "^8.0.0" @@ -1977,10 +1992,10 @@ conventional-changelog-writer@^5.0.0: split "^1.0.0" through2 "^4.0.0" -conventional-changelog@^3.1.24: - version "3.1.24" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.24.tgz#ebd180b0fd1b2e1f0095c4b04fd088698348a464" - integrity sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg== +conventional-changelog@^3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.25.tgz#3e227a37d15684f5aa1fb52222a6e9e2536ccaff" + integrity sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ== dependencies: conventional-changelog-angular "^5.0.12" conventional-changelog-atom "^2.0.8" @@ -2008,9 +2023,9 @@ conventional-commits-filter@^2.0.7: modify-values "^1.0.0" conventional-commits-parser@^3.2.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz#fc43704698239451e3ef35fd1d8ed644f46bd86e" - integrity sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw== + version "3.2.4" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972" + integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q== dependencies: JSONStream "^1.0.4" is-text-path "^1.0.1" @@ -2041,9 +2056,9 @@ convert-source-map@^1.7.0: safe-buffer "~5.1.1" cookie@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== core-util-is@1.0.2: version "1.0.2" @@ -2055,7 +2070,15 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@7.0.1, cosmiconfig@^7.0.0: +cosmiconfig-typescript-loader@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.5.tgz#22373003194a1887bbccbdfd05a13501397109a8" + integrity sha512-FL/YR1nb8hyN0bAcP3MBaIoZravfZtVsN/RuPnoo6UVjqIrDxSNIpXHCGgJe0ZWy5yImpyD6jq5wCJ5f1nUv8g== + dependencies: + cosmiconfig "^7" + ts-node "^10.5.0" + +cosmiconfig@7.0.1, cosmiconfig@^7, cosmiconfig@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== @@ -2071,13 +2094,6 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-env@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" - integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== - dependencies: - cross-spawn "^7.0.0" - cross-env@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -2151,7 +2167,7 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -dateformat@^3.0.0, dateformat@^3.0.3: +dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== @@ -2161,11 +2177,6 @@ dayjs@^1.10.7: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468" integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig== -debounce@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" - integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== - debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2173,20 +2184,20 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: +debug@4.3.3, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: 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" +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -2292,14 +2303,6 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -deprecated-obj@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/deprecated-obj/-/deprecated-obj-2.0.0.tgz#e6ba93a3989f6ed18d685e7d99fb8d469b4beffc" - integrity sha512-CkdywZC2rJ8RGh+y3MM1fw1EJ4oO/oNExGbRFv0AQoMS+faTd3nO7slYjkj/6t8OnIMUE+wxh6G97YHhK1ytrw== - dependencies: - flat "^5.0.2" - lodash "^4.17.20" - deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -2325,10 +2328,10 @@ detect-libc@^1.0.3: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= -diff-sequences@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" - integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== diff@5.0.0, diff@^5.0.0: version "5.0.0" @@ -2376,12 +2379,10 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -dynamic-dedupe@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" - integrity sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE= - dependencies: - xtend "^4.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecc-jsbn@~0.1.1: version "0.1.2" @@ -2392,9 +2393,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.4.17: - version "1.4.21" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.21.tgz#edf7d9477980079d840570c34ab4c4a5bef4c2bd" - integrity sha512-T04U2ciApGbm+dESFEBbewi2Xt0Dgyww8M4n4sOt9lnmFuYbaHEDWCROkx4jvAZDUWWry9YOdnAs+7468q80Qg== + version "1.4.71" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6" + integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw== emoji-regex@^8.0.0: version "8.0.0" @@ -2413,14 +2414,7 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -error-ex@^1.3.1: +error-ex@^1.3.1, error-ex@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -2442,170 +2436,180 @@ esbuild-android-arm64@0.13.15: resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" integrity sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg== -esbuild-android-arm64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.5.tgz#a7bc2263e099b67d1d6bc10ad504f396b439a42a" - integrity sha512-Sl6ysm7OAZZz+X3Mv3tOPhjMuSxNmztgoXH4ZZ3Yhbje5emEY6qiTnv3vBSljDlUl/yGaIjqC44qlj8s8G71xA== +esbuild-android-arm64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.22.tgz#fb051169a63307d958aec85ad596cfc7d7770303" + integrity sha512-k1Uu4uC4UOFgrnTj2zuj75EswFSEBK+H6lT70/DdS4mTAOfs2ECv2I9ZYvr3w0WL0T4YItzJdK7fPNxcPw6YmQ== esbuild-darwin-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72" integrity sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ== -esbuild-darwin-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.5.tgz#589f4b8663feb044f2425e70618f6a9debebaf14" - integrity sha512-VHZl23sM9BOZXcLxk1vTYls8TCAY+/3llw9vHKIWAHDHzBBOlVv26ORK8gnStNMqTjCSGSMoq4T5jOZf2WrJPQ== +esbuild-darwin-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.22.tgz#615ea0a9de67b57a293a7128d7ac83ee307a856d" + integrity sha512-d8Ceuo6Vw6HM3fW218FB6jTY6O3r2WNcTAU0SGsBkXZ3k8SDoRLd3Nrc//EqzdgYnzDNMNtrWegK2Qsss4THhw== esbuild-darwin-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a" integrity sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ== -esbuild-darwin-arm64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.5.tgz#c4def102fddd52ccaf23cf00c3274296de6b12db" - integrity sha512-ugPOLgEQPoPLSqAFBajaczt+lcbUZR+V2fby3572h5jf/kFV6UL8LAZ1Ze58hcbKwfvbh4C09kp0PhqPgXKwOg== +esbuild-darwin-arm64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.22.tgz#82054dcfcecb15ccfd237093b8008e7745a99ad9" + integrity sha512-YAt9Tj3SkIUkswuzHxkaNlT9+sg0xvzDvE75LlBo4DI++ogSgSmKNR6B4eUhU5EUUepVXcXdRIdqMq9ppeRqfw== esbuild-freebsd-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85" integrity sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA== -esbuild-freebsd-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.5.tgz#e5152bbf256942fe498dfe4a5f92b8bb148a64b5" - integrity sha512-uP0yOixSHF505o/Kzq9e4bvZblCZp9GGx+a7enLOVSuvIvLmtj2yhZLRPGfbVNkPJXktTKNRAnNGkXHl53M6sw== +esbuild-freebsd-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.22.tgz#778a818c5b078d5cdd6bb6c0e0797217d196999b" + integrity sha512-ek1HUv7fkXMy87Qm2G4IRohN+Qux4IcnrDBPZGXNN33KAL0pEJJzdTv0hB/42+DCYWylSrSKxk3KUXfqXOoH4A== esbuild-freebsd-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52" integrity sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ== -esbuild-freebsd-arm64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.5.tgz#7c1ad25ae9ed101df76dc64d83fcfd2ddba5aed0" - integrity sha512-M99NPu8hlirFo6Fgx0WfX6XxUFdGclUNv3MyyfDtTdNYbccMESwLSACGpE7HvJKWscdjaqajeMu2an9adGNfCw== +esbuild-freebsd-arm64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.22.tgz#18da93b9f3db2e036f72383bfe73b28b73bb332c" + integrity sha512-zPh9SzjRvr9FwsouNYTqgqFlsMIW07O8mNXulGeQx6O5ApgGUBZBgtzSlBQXkHi18WjrosYfsvp5nzOKiWzkjQ== esbuild-linux-32@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69" integrity sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g== -esbuild-linux-32@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.5.tgz#047a2d6d9dd5f85e6e6875b048c41ab2515e12ce" - integrity sha512-hfqln4yb/jf/vPvI/A6aCvpIzqF3PdDmrKiikTohEUuRtvEZz234krtNwEAw5ssCue4NX8BJqrMpCTAHOl3LQw== +esbuild-linux-32@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.22.tgz#d0d5d9f5bb3536e17ac097e9512019c65b7c0234" + integrity sha512-SnpveoE4nzjb9t2hqCIzzTWBM0RzcCINDMBB67H6OXIuDa4KqFqaIgmTchNA9pJKOVLVIKd5FYxNiJStli21qg== esbuild-linux-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3" integrity sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA== -esbuild-linux-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.5.tgz#03793b5a0ae450c725616fc724b3a406cd2da2fa" - integrity sha512-T+OuYPlhytjj5DsvjUXizNjbV+/IrZiaDc9SNUfqiUOXHu0URFqchjhPVbBiBnWykCMJFB6pqNap2Oxth4iuYw== +esbuild-linux-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.22.tgz#2773d540971999ea7f38107ef92fca753f6a8c30" + integrity sha512-Zcl9Wg7gKhOWWNqAjygyqzB+fJa19glgl2JG7GtuxHyL1uEnWlpSMytTLMqtfbmRykIHdab797IOZeKwk5g0zg== esbuild-linux-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1" integrity sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA== -esbuild-linux-arm64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.5.tgz#9217283b5ccaf2ec9a31f9b4eaeb5787607252a3" - integrity sha512-ANOzoaH4kfbhEZT0EGY9g1tsZhDA+I0FRwBsj7D8pCU900pXF/l8YAOy5jWFQIb3vjG5+orFc5SqSzAKCisvTQ== +esbuild-linux-arm64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.22.tgz#5d4480ce6d6bffab1dd76a23158f5a5ab33e7ba4" + integrity sha512-8q/FRBJtV5IHnQChO3LHh/Jf7KLrxJ/RCTGdBvlVZhBde+dk3/qS9fFsUy+rs3dEi49aAsyVitTwlKw1SUFm+A== esbuild-linux-arm@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe" integrity sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA== -esbuild-linux-arm@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.5.tgz#e048a681e7f42b12cac1db4a34a84ef17e219333" - integrity sha512-5b10jKJ3lU4BUchOw9TgRResu8UZJf8qVjAzV5muHedonCfBzClGTT4KCNuOcLTJomH3wz6gNVJt1AxMglXnJg== +esbuild-linux-arm@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.22.tgz#c6391b3f7c8fa6d3b99a7e893ce0f45f3a921eef" + integrity sha512-soPDdbpt/C0XvOOK45p4EFt8HbH5g+0uHs5nUKjHVExfgR7du734kEkXR/mE5zmjrlymk5AA79I0VIvj90WZ4g== esbuild-linux-mips64le@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7" integrity sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg== -esbuild-linux-mips64le@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.5.tgz#c1817c00023d8a1c8fe507e60c63cf8a602bce29" - integrity sha512-sSmGfOUNNB2Nd3tzp1RHSxiJmM5/RUIEP5aAtH+PpOP7FPp15Jcfwq7UNBJ82KLN3SJcwhUeEfcCaUFBzbTKxg== +esbuild-linux-mips64le@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.22.tgz#2c8dabac355c502e86c38f9f292b3517d8e181f3" + integrity sha512-SiNDfuRXhGh1JQLLA9JPprBgPVFOsGuQ0yDfSPTNxztmVJd8W2mX++c4FfLpAwxuJe183mLuKf7qKCHQs5ZnBQ== esbuild-linux-ppc64le@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2" integrity sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ== -esbuild-linux-ppc64le@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.5.tgz#5fa1178c7d7ebd13056c7ccd0604653b0ccc2264" - integrity sha512-usfQrVVIQcpuc/U2NWc7/Ry+m622v+PjJ5eErNPdjWBPlcvD6kXaBTv94uQkVzZOHX3uYqprRrOjseed9ApSYA== +esbuild-linux-ppc64le@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.22.tgz#69d71b2820d5c94306072dac6094bae38e77d1c0" + integrity sha512-6t/GI9I+3o1EFm2AyN9+TsjdgWCpg2nwniEhjm2qJWtJyJ5VzTXGUU3alCO3evopu8G0hN2Bu1Jhz2YmZD0kng== + +esbuild-linux-riscv64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.22.tgz#c0ec0fc3a23624deebf657781550d2329cec4213" + integrity sha512-AyJHipZKe88sc+tp5layovquw5cvz45QXw5SaDgAq2M911wLHiCvDtf/07oDx8eweCyzYzG5Y39Ih568amMTCQ== + +esbuild-linux-s390x@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.22.tgz#ec2af4572d63336cfb27f5a5c851fb1b6617dd91" + integrity sha512-Sz1NjZewTIXSblQDZWEFZYjOK6p8tV6hrshYdXZ0NHTjWE+lwxpOpWeElUGtEmiPcMT71FiuA9ODplqzzSxkzw== esbuild-netbsd-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038" integrity sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w== -esbuild-netbsd-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.5.tgz#757572c7664ae6122c8e4dd89a2b6d337c3c27b2" - integrity sha512-Q5KpvPZcPnNEaTjrvuWqvEnlhI2jyi1wWwYunlEUAhx60spQOTy10sdYOA+s1M+LPb6kwvasrZZDmYyQlcVZeA== +esbuild-netbsd-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.22.tgz#0e283278e9fdbaa7f0930f93ee113d7759cd865e" + integrity sha512-TBbCtx+k32xydImsHxvFgsOCuFqCTGIxhzRNbgSL1Z2CKhzxwT92kQMhxort9N/fZM2CkRCPPs5wzQSamtzEHA== esbuild-openbsd-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7" integrity sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g== -esbuild-openbsd-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.5.tgz#046827c211daa2b6a2241a9f910321e116d2cc24" - integrity sha512-RZzRUu1RYKextJgXkHhAsuhLDvm73YP/wogpUG9MaAGvKTxnKAKRuaw2zJfnbz8iBqBQB2no2PmpVBNbqUTQrw== +esbuild-openbsd-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.22.tgz#2a73bba04e16d8ef278fbe2be85248e12a2f2cc2" + integrity sha512-vK912As725haT313ANZZZN+0EysEEQXWC/+YE4rQvOQzLuxAQc2tjbzlAFREx3C8+uMuZj/q7E5gyVB7TzpcTA== esbuild-sunos-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4" integrity sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw== -esbuild-sunos-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.5.tgz#3e2b0e79188069a366faec3d5b1b3065b792a733" - integrity sha512-J2ffKsBBWscQlye+/giEgKsQCppwHHFqqt/sh+ojVF+DZy1ve6RpPGwXGcGF6IaZTAI9+Vk4eHleiQxb+PC9Yw== +esbuild-sunos-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.22.tgz#8fe03513b8b2e682a6d79d5e3ca5849651a3c1d8" + integrity sha512-/mbJdXTW7MTcsPhtfDsDyPEOju9EOABvCjeUU2OJ7fWpX/Em/H3WYDa86tzLUbcVg++BScQDzqV/7RYw5XNY0g== esbuild-windows-32@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7" integrity sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw== -esbuild-windows-32@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.5.tgz#520f3737719177d76955b8f1c34eca8e8d005eba" - integrity sha512-OTZvuAc1JBnwmeT+hR1+Vmgz6LOD7DggpnwtKMAExruSLxUMl02Z3pyalJ7zKh3gJ/KBRM1JQZLSk4/mFWijeQ== +esbuild-windows-32@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.22.tgz#a75df61e3e49df292a1842be8e877a3153ee644f" + integrity sha512-1vRIkuvPTjeSVK3diVrnMLSbkuE36jxA+8zGLUOrT4bb7E/JZvDRhvtbWXWaveUc/7LbhaNFhHNvfPuSw2QOQg== esbuild-windows-64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294" integrity sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ== -esbuild-windows-64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.5.tgz#0100d8aa3c5d57e676aeb37975e948880f751650" - integrity sha512-ZM9rlBDsPEeMVJ1wcpNMXUad9VzYOFeOBUXBi+16HZTvFPy2DkcC2ZWcrByP3IESToD5lvHdjSX/w8rxphjqig== +esbuild-windows-64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.22.tgz#d06cf8bbe4945b8bf95a730d871e54a22f635941" + integrity sha512-AxjIDcOmx17vr31C5hp20HIwz1MymtMjKqX4qL6whPj0dT9lwxPexmLj6G1CpR3vFhui6m75EnBEe4QL82SYqw== esbuild-windows-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3" integrity sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA== -esbuild-windows-arm64@0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.5.tgz#c1d575f2c6d27159de9b5d273bcde02445f17a1d" - integrity sha512-iK41mKG2LG0AKHE+9g/jDYU5ZQpJObt1uIPSGTiiiJKI5qbHdEck6Gaqq2tmBI933F2zB9yqZIX7IAdxwN/q4A== +esbuild-windows-arm64@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.22.tgz#f8b1b05c548073be8413a5ecb12d7c2f6e717227" + integrity sha512-5wvQ+39tHmRhNpu2Fx04l7QfeK3mQ9tKzDqqGR8n/4WUxsFxnVLfDRBGirIfk4AfWlxk60kqirlODPoT5LqMUg== esbuild@^0.13.13: version "0.13.15" @@ -2630,28 +2634,30 @@ esbuild@^0.13.13: esbuild-windows-64 "0.13.15" esbuild-windows-arm64 "0.13.15" -esbuild@^0.14.5: - version "0.14.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.5.tgz#45ef0287a94cc7a3d367621e4a7ba470a847669f" - integrity sha512-ofwgH4ITPXhkMo2AM39oXpSe5KIyWjxicdqYVy+tLa1lMgxzPCKwaepcrSRtYbgTUMXwquxB1C3xQYpUNaPAFA== +esbuild@^0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.22.tgz#2b55fde89d7aa5aaaad791816d58ff9dfc5ed085" + integrity sha512-CjFCFGgYtbFOPrwZNJf7wsuzesx8kqwAffOlbYcFDLFuUtP8xloK1GH+Ai13Qr0RZQf9tE7LMTHJ2iVGJ1SKZA== optionalDependencies: - esbuild-android-arm64 "0.14.5" - esbuild-darwin-64 "0.14.5" - esbuild-darwin-arm64 "0.14.5" - esbuild-freebsd-64 "0.14.5" - esbuild-freebsd-arm64 "0.14.5" - esbuild-linux-32 "0.14.5" - esbuild-linux-64 "0.14.5" - esbuild-linux-arm "0.14.5" - esbuild-linux-arm64 "0.14.5" - esbuild-linux-mips64le "0.14.5" - esbuild-linux-ppc64le "0.14.5" - esbuild-netbsd-64 "0.14.5" - esbuild-openbsd-64 "0.14.5" - esbuild-sunos-64 "0.14.5" - esbuild-windows-32 "0.14.5" - esbuild-windows-64 "0.14.5" - esbuild-windows-arm64 "0.14.5" + esbuild-android-arm64 "0.14.22" + esbuild-darwin-64 "0.14.22" + esbuild-darwin-arm64 "0.14.22" + esbuild-freebsd-64 "0.14.22" + esbuild-freebsd-arm64 "0.14.22" + esbuild-linux-32 "0.14.22" + esbuild-linux-64 "0.14.22" + esbuild-linux-arm "0.14.22" + esbuild-linux-arm64 "0.14.22" + esbuild-linux-mips64le "0.14.22" + esbuild-linux-ppc64le "0.14.22" + esbuild-linux-riscv64 "0.14.22" + esbuild-linux-s390x "0.14.22" + esbuild-netbsd-64 "0.14.22" + esbuild-openbsd-64 "0.14.22" + esbuild-sunos-64 "0.14.22" + esbuild-windows-32 "0.14.22" + esbuild-windows-64 "0.14.22" + esbuild-windows-arm64 "0.14.22" escalade@^3.1.1: version "3.1.1" @@ -2691,10 +2697,10 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153" - integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -2711,29 +2717,28 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" - integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.4.1.tgz#d6531bbf3e598dffd7c0c7d35ec52a0b30fdfa2d" - integrity sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg== +eslint@^8.9.0: + version "8.9.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.9.0.tgz#a2a8227a99599adc4342fd9b854cb8d8d6412fdb" + integrity sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q== dependencies: - "@eslint/eslintrc" "^1.0.5" + "@eslint/eslintrc" "^1.1.0" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.0" + eslint-scope "^7.1.1" eslint-utils "^3.0.0" - eslint-visitor-keys "^3.1.0" - espree "^9.2.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -2741,7 +2746,7 @@ eslint@^8.4.1: functional-red-black-tree "^1.0.1" glob-parent "^6.0.1" globals "^13.6.0" - ignore "^4.0.6" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" @@ -2752,22 +2757,20 @@ eslint@^8.4.1: minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" regexpp "^3.2.0" - semver "^7.2.1" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.2.0.tgz#c50814e01611c2d0f8bd4daa83c369eabba80dbc" - integrity sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg== +espree@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" + integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== dependencies: - acorn "^8.6.0" + acorn "^8.7.0" acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.1.0" + eslint-visitor-keys "^3.3.0" esprima@^4.0.0: version "4.0.1" @@ -2850,17 +2853,15 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.2.tgz#4429b0f7e307771d176de9bdf23229b101db6ef6" - integrity sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg== +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: - "@jest/types" "^27.4.2" - ansi-styles "^5.0.0" - jest-get-type "^27.4.0" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-regex-util "^27.4.0" + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" extend@^3.0.0, extend@~3.0.2: version "3.0.2" @@ -2886,11 +2887,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -faker@^5.5.3: - version "5.5.3" - resolved "https://registry.yarnpkg.com/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e" - integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g== - fast-decode-uri-component@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" @@ -2901,10 +2897,10 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1, fast-glob@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== +fast-glob@^3.1.1, fast-glob@^3.2.7, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -2918,9 +2914,9 @@ fast-json-stable-stringify@^2.0.0: integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-json-stringify@^2.5.2: - version "2.7.12" - resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.12.tgz#5bb7941695b52f545191bc396396230633f43592" - integrity sha512-4hjwZDPmgj/ZUKXhEWovGPciE/5mWtAIQQxN+2VBDFun7DRTk2oOItbu9ZZp6kqj+eZ/u7z+dgBgM74cfGRnBQ== + version "2.7.13" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz#277aa86c2acba4d9851bd6108ed657aa327ed8c0" + integrity sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA== dependencies: ajv "^6.11.0" deepmerge "^4.2.2" @@ -2933,9 +2929,9 @@ fast-levenshtein@^2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-redact@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.2.tgz#c940ba7162dde3aeeefc522926ae8c5231412904" - integrity sha512-YN+CYfCVRVMUZOUPeinHNKgytM1wPI/C/UCLEi56EsY2dwwvI00kIJHJoI7pMVqGoMew8SMZ2SSfHKHULHXDsg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.0.tgz#37c26cda9cab70bc04393f7ba1feb2d176da6c6b" + integrity sha512-dir8LOnvialLxiXDPESMDHGp82CHi6ZEYTVkcvdn5d7psdv9ZkkButXrOeXST4aqreIRR+N7CYlsrwFuorurVg== fast-safe-stringify@^2.0.8: version "2.1.1" @@ -2952,21 +2948,21 @@ fastify-warning@^0.2.0: resolved "https://registry.yarnpkg.com/fastify-warning/-/fastify-warning-0.2.0.tgz#e717776026a4493dc9a2befa44db6d17f618008f" integrity sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw== -fastify@^3.25.0: - version "3.25.0" - resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.25.0.tgz#04b682fa738c6468bc36efba9f1e943609502111" - integrity sha512-GblpjS7yuJ9jpkz1guHTyzlVQn9NYvGrMkDLtoxctEt7n1d6MSwA9i3p10HjNiY+zVurPf3YdOqXsJmVgAR3cg== +fastify@^3.27.1: + version "3.27.1" + resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.27.1.tgz#7e976473c15d7dc405ad624ffafb6612a6281d10" + integrity sha512-GLn3ow5BGqg/m+ztXvztp8Xp7SuH99vAm4zfbN7407Qzi4mB055SG/lWH/gYolz5Oq2K8LtUpZqt1Ccf/YkVmA== dependencies: "@fastify/ajv-compiler" "^1.0.0" abstract-logging "^2.0.0" avvio "^7.1.2" fast-json-stringify "^2.5.2" fastify-error "^0.3.0" - fastify-warning "^0.2.0" - find-my-way "^4.1.0" + find-my-way "^4.5.0" flatstr "^1.0.12" light-my-request "^4.2.0" pino "^6.13.0" + process-warning "^1.0.0" proxy-addr "^2.0.7" rfdc "^1.1.4" secure-json-parse "^2.0.0" @@ -3042,13 +3038,6 @@ file-type@^9.0.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== -filewatcher@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/filewatcher/-/filewatcher-3.0.1.tgz#f4a1957355ddaf443ccd78a895f3d55e23c8a034" - integrity sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ= - dependencies: - debounce "^1.0.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -3070,10 +3059,10 @@ find-cache-dir@^3.2.0: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-my-way@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-4.5.0.tgz#885ceb7a60b9be529a11dbfed02c8cf0ab7eedb7" - integrity sha512-kVEY1lW/zXETKEEwRboCWPySygBFVNJpdY7lRnFllDdYxQD6cwcaT3Ddh8P7v824jRN3cld+8+zRbnFBxeVUxA== +find-my-way@^4.5.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-4.5.1.tgz#758e959194b90aea0270db18fff75e2fceb2239f" + integrity sha512-kE0u7sGoUFbMXcOG/xpkmz4sRLCklERnBcg7Ftuu1iAxsfEt2S46RLJ3Sq7vshsEy2wJT2hZxE58XZK27qa8kg== dependencies: fast-decode-uri-component "^1.0.1" fast-deep-equal "^3.1.3" @@ -3152,9 +3141,9 @@ flatstr@^1.0.12: integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== flatted@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" - integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== foreground-child@^2.0.0: version "2.0.0" @@ -3336,9 +3325,9 @@ gifwrap@^0.9.2: omggif "^1.0.10" git-raw-commits@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" - integrity sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ== + version "2.0.11" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" + integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== dependencies: dargs "^7.0.0" lodash "^4.17.15" @@ -3420,19 +3409,7 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - 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" - -glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: +glob@7.2.0, glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -3492,13 +3469,13 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" - integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== dependencies: type-fest "^0.20.2" -globby@11.0.4, globby@^11.0.4: +globby@11.0.4: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -3510,6 +3487,18 @@ globby@11.0.4, globby@^11.0.4: merge2 "^1.3.0" slash "^3.0.0" +globby@^11.0.4: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + 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" + got@11.8.3: version "11.8.3" resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" @@ -3544,21 +3533,16 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== 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== -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - gzip-size@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-7.0.0.tgz#9f9644251f15bc78460fccef4055ae5a5562ac60" @@ -3566,7 +3550,7 @@ gzip-size@^7.0.0: dependencies: duplexer "^0.1.2" -handlebars@^4.7.6: +handlebars@^4.7.7: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== @@ -3654,9 +3638,9 @@ hosted-git-info@^2.1.4: integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" - integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" @@ -3709,15 +3693,20 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.0, ignore@^5.1.4, ignore@^5.1.8: - version "5.1.9" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" - integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== +ignore@^5.0.0, ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== image-q@^1.1.1: version "1.1.1" @@ -3903,10 +3892,10 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0, is-core-module@^2.5.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== +is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== dependencies: has "^1.0.3" @@ -3942,11 +3931,6 @@ is-fullwidth-code-point@^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-fullwidth-code-point@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - is-function@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" @@ -4051,7 +4035,7 @@ is-windows@^1.0.1, is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-wsl@^2.1.1, is-wsl@^2.2.0: +is-wsl@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -4132,58 +4116,53 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.1.tgz#7085857f17d2441053c6ce5c3b8fdf6882289397" - integrity sha512-q1kvhAXWSsXfMjCdNHNPKZZv94OlspKnoGv+R9RGbnqOOQ0VbNfLFgQDVgi7hHenKsndGq3/o0OBdzDXthWcNw== + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-diff@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" - integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== dependencies: chalk "^4.0.0" - diff-sequences "^27.4.0" - jest-get-type "^27.4.0" - pretty-format "^27.4.2" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-get-type@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" - integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-matcher-utils@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" - integrity sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ== +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== dependencies: chalk "^4.0.0" - jest-diff "^27.4.2" - jest-get-type "^27.4.0" - pretty-format "^27.4.2" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-message-util@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.2.tgz#07f3f1bf207d69cf798ce830cc57f1a849f99388" - integrity sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w== +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.4.2" + "@jest/types" "^27.5.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.4.2" + pretty-format "^27.5.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-regex-util@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" - integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== - jimp@^0.16.1: version "0.16.1" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.16.1.tgz#192f851a30e5ca11112a3d0aa53137659a78ca7a" @@ -4217,22 +4196,7 @@ jimp@^0.2.21: tinycolor2 "^1.1.2" url-regex "^3.0.0" -jpeg-js@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d" - integrity sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw== - -jpeg-js@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" - integrity sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4= - -jpeg-js@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" - integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII= - -jpeg-js@^0.4.1: +jpeg-js@0.4.2, jpeg-js@^0.1.1, jpeg-js@^0.2.0, jpeg-js@^0.4.0, jpeg-js@^0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q== @@ -4282,7 +4246,7 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-parse-even-better-errors@^2.3.0: +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== @@ -4363,9 +4327,9 @@ keyv@^3.0.0: json-buffer "3.0.0" keyv@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.4.tgz#f040b236ea2b06ed15ed86fbef8407e1a1c8e376" - integrity sha512-vqNHbAc8BBsxk+7QBYLW0Y219rWcClspR6WSeoHYKG5mnsSoOH+BL1pWq02DDCVdvvuUny5rkBlzMRzoqc+GIg== + version "4.1.1" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.1.1.tgz#02c538bfdbd2a9308cc932d4096f05ae42bfa06a" + integrity sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ== dependencies: json-buffer "3.0.1" @@ -4409,9 +4373,9 @@ libnpmconfig@^1.0.0: ini "^1.3.5" light-my-request@^4.2.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.7.0.tgz#5bacd17fa0eaf96fe5eed1682c5e0d361953cf46" - integrity sha512-LTa8YZp3K2AUpqUnwwKajoIHcsKOBnzwJNQSrk7unziPwo6CjOYjyO0F9wfkxFvP+nBsCGe3eMPnedVgIIgdAw== + version "4.7.1" + resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.7.1.tgz#deb33c4485a08395760f16e5a7a044e6102bb4c4" + integrity sha512-7/bT6M+iHY90L9/rW7aboVYt0o0uOqzIx4yofC67d6WE9uLksecGf3mxPuZfVjMONG+i6hCq6z5NZCxqzpA2yw== dependencies: ajv "^8.1.0" cookie "^0.4.0" @@ -4423,6 +4387,11 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +lines-and-columns@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" + integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + load-bmfont@^1.2.3, load-bmfont@^1.3.1, load-bmfont@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9" @@ -4495,11 +4464,6 @@ lodash.flattendeep@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.get@^4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -4567,7 +4531,7 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" -make-error@^1, make-error@^1.1.1: +make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -4601,9 +4565,9 @@ mdast-util-from-markdown@^1.0.0: uvu "^0.5.0" mdast-util-to-markdown@^1.0.0: - version "1.2.6" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.6.tgz#9d0d1fcb22838e4af83fb04841cbde92525972f3" - integrity sha512-doJZmTEGagHypWvJ8ltinmwUsT9ZaNgNIQW6Gl7jNdsI1QZkTHTimYW561Niy2s8AEPAqEgV0dIh2UOVlSXUJA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz#38b6cdc8dc417de642a469c4fc2abdf8c931bd1e" + integrity sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA== dependencies: "@types/mdast" "^3.0.0" "@types/unist" "^2.0.0" @@ -4654,7 +4618,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -4784,9 +4748,9 @@ micromark-util-decode-string@^1.0.0: micromark-util-symbol "^1.0.0" micromark-util-encode@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz#c409ecf751a28aa9564b599db35640fccec4c068" - integrity sha512-cJpFVM768h6zkd8qJ1LNRrITfY4gwFt+tziPcIf71Ui8yFzY9wG3snZQqiWVq93PG4Sw6YOtcNiKJfVIs9qfGg== + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383" + integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA== micromark-util-html-tag-name@^1.0.0: version "1.0.0" @@ -4872,7 +4836,7 @@ mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@2.1.34, mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@2.1.34, mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.34: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== @@ -4921,13 +4885,20 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 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" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -4961,32 +4932,32 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.5" -mocha@^9.1.3: - version "9.1.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.3.tgz#8a623be6b323810493d8c8f6f7667440fa469fdb" - integrity sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw== +mocha@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" + integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" + 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.1.7" + glob "7.2.0" growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" minimatch "3.0.4" ms "2.1.3" - nanoid "3.1.25" + nanoid "3.2.0" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" which "2.0.2" - workerpool "6.1.5" + workerpool "6.2.0" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -5011,7 +4982,7 @@ ms@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.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== @@ -5026,15 +4997,15 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== +nanoid@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== -nanoid@^3.1.30: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== +nanoid@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== napi-build-utils@^1.0.1: version "1.0.2" @@ -5062,10 +5033,10 @@ ndarray@^1.0.13, ndarray@^1.0.19: iota-array "^1.0.0" is-buffer "^1.0.2" -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.6.0: version "2.6.2" @@ -5101,43 +5072,13 @@ node-bitmap@0.0.1: resolved "https://registry.yarnpkg.com/node-bitmap/-/node-bitmap-0.0.1.tgz#180eac7003e0c707618ef31368f62f84b2a69091" integrity sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE= -node-dev@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/node-dev/-/node-dev-7.1.0.tgz#b3294e4171b3cd7caa894480e006cd9e4d16ff0c" - integrity sha512-wvlX+XQVGdwin0CQrWWCNvhb6Sf2FB/zNLFleg3o5Ml6jhAwWXKMX1JSP/1RSyf0atLXxD/L3vl7pNVJgClv/w== - dependencies: - dateformat "^3.0.3" - dynamic-dedupe "^0.3.0" - filewatcher "~3.0.0" - minimist "^1.2.5" - node-notifier "^8.0.1" - resolve "^1.0.0" - semver "^7.3.5" - -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@^2.6.1: - version "2.6.6" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" - integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== +node-fetch@2.6.7, node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" -node-notifier@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" - integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== - dependencies: - growly "^1.3.0" - is-wsl "^2.2.0" - semver "^7.3.2" - shellwords "^0.1.1" - uuid "^8.3.0" - which "^2.0.2" - node-preload@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" @@ -5146,9 +5087,32 @@ node-preload@^0.2.1: process-on-spawn "^1.0.0" node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +nodemon@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" + integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.8" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + update-notifier "^5.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" @@ -5251,9 +5215,9 @@ object-assign@^4.0.1, object-assign@^4.1.0: integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-inspect@^1.9.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b" - integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA== + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" @@ -5483,6 +5447,16 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-6.0.2.tgz#6bf79c201351cc12d5d66eba48d5a097c13dc200" + integrity sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA== + dependencies: + "@babel/code-frame" "^7.16.0" + error-ex "^1.3.2" + json-parse-even-better-errors "^2.3.1" + lines-and-columns "^2.0.2" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -5540,7 +5514,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -5573,9 +5547,9 @@ picocolors@^1.0.0: integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pify@^2.3.0: version "2.3.0" @@ -5605,22 +5579,22 @@ pino-std-serializers@^3.1.0: integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== pino@^6.13.0: - version "6.13.3" - resolved "https://registry.yarnpkg.com/pino/-/pino-6.13.3.tgz#60b93bcda1541f92fb37b3f2be0a25cf1d05b6fe" - integrity sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg== + version "6.14.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-6.14.0.tgz#b745ea87a99a6c4c9b374e4f29ca7910d4c69f78" + integrity sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg== dependencies: fast-redact "^3.0.0" fast-safe-stringify "^2.0.8" - fastify-warning "^0.2.0" flatstr "^1.0.12" pino-std-serializers "^3.1.0" + process-warning "^1.0.0" quick-format-unescaped "^4.0.3" sonic-boom "^1.0.2" -pirates@^4.0.1, pirates@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" - integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== +pirates@^4.0.1, pirates@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pixelmatch@^4.0.0, pixelmatch@^4.0.2: version "4.0.2" @@ -5647,21 +5621,21 @@ pngjs@^5.0.0: integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== postcss-selector-parser@^6.0.6: - version "6.0.7" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.7.tgz#48404830a635113a71fd79397de8209ed05a66fc" - integrity sha512-U+b/Deoi4I/UmE6KOVPpnhS7I7AYdKbhGcat+qTQ27gycvaACvNEw11ba6RrkwVmDVRW7sigWgLj4/KbbJjeDA== + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" postcss@^8.3.5: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + version "8.4.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" + integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== dependencies: - nanoid "^3.1.30" + nanoid "^3.2.0" picocolors "^1.0.0" - source-map-js "^1.0.1" + source-map-js "^1.0.2" prebuild-install@^6.1.2: version "6.1.4" @@ -5688,11 +5662,10 @@ prelude-ls@^1.2.1: integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prepend-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-file/-/prepend-file-2.0.0.tgz#2d3256376a64ca3b5640153890a89cadbebaf1a9" - integrity sha512-U6on3jv5hQ+CNEO7gFn00PUlm3F/oXIQTMg6jpeQTQHLYSZl/Cxb4NpH44FA0By+maPXpfUaqmCoPUTu/Z3/8g== + version "2.0.1" + resolved "https://registry.yarnpkg.com/prepend-file/-/prepend-file-2.0.1.tgz#6a624b474a65ab1f87dc24d1757d5a6d989eb2db" + integrity sha512-0hXWjmOpz5YBIk6xujS0lYtCw6IAA0wCR3fw49UGTLc3E9BIhcxgqdMa8rzGvrtt2F8wFiGP42oEpQ8fo9zhRw== dependencies: - path-exists "^4.0.0" temp-write "^4.0.0" prepend-http@^2.0.0: @@ -5700,12 +5673,11 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -pretty-format@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" - integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== +pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "@jest/types" "^27.4.2" ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -5722,16 +5694,16 @@ process-on-spawn@^1.0.0: dependencies: fromentries "^1.2.0" +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - protocols@^1.1.0, protocols@^1.4.0: version "1.4.8" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" @@ -5750,6 +5722,11 @@ psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -5786,16 +5763,16 @@ q@^1.5.1: integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qs@^6.9.4: - version "6.10.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.2.tgz#c1431bea37fc5b24c5bdbafa20f16bdf2a4b9ffe" - integrity sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw== + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== dependencies: side-channel "^1.0.4" qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== query-string@^6.13.8: version "6.14.1" @@ -5965,18 +5942,17 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -release-it@^14.11.8: - version "14.11.8" - resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.11.8.tgz#6da25daa93286d832cae4f10008a3bf0c08c2725" - integrity sha512-951DJ0kwjwU7CwGU3BCvRBgLxuJsOPRrZkqx0AsugJdSyPpUdwY9nlU0RAoSKqgh+VTerzecXLIIwgsGIpNxlA== +release-it@^14.12.4: + version "14.12.4" + resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.12.4.tgz#0fd13de85e382323c634a0697a601437e042123a" + integrity sha512-lqf9PMsj7ycCqFHGag8Uv7cE1hNsKa+yKUMe+Fkh9fdOfxu2F01On+YUefRCP0DuQthmr/WyLCYdrjThMEkWFQ== dependencies: "@iarna/toml" "2.2.5" "@octokit/rest" "18.12.0" async-retry "1.3.3" chalk "4.1.2" cosmiconfig "7.0.1" - debug "4.3.2" - deprecated-obj "2.0.0" + debug "4.3.3" execa "5.1.1" form-data "4.0.0" git-url-parse "11.6.0" @@ -5993,7 +5969,7 @@ release-it@^14.11.8: os-name "4.0.1" parse-json "5.2.0" semver "7.3.5" - shelljs "0.8.4" + shelljs "0.8.5" update-notifier "5.1.0" url-join "4.0.1" uuid "8.3.2" @@ -6145,13 +6121,14 @@ resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" -resolve@^1.0.0, resolve@^1.1.6, resolve@^1.10.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== +resolve@^1.1.6, resolve@^1.10.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" responselike@^1.0.2: version "1.0.2" @@ -6230,16 +6207,16 @@ rxjs@^6.4.0: tslib "^1.9.0" rxjs@^7.2.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68" - integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w== + version "7.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d" + integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ== dependencies: - tslib "~2.1.0" + tslib "^2.1.0" sade@^1.7.3: - version "1.7.4" - resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691" - integrity sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA== + version "1.8.1" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" + integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== dependencies: mri "^1.1.0" @@ -6287,12 +6264,12 @@ semver-store@^0.3.0: resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== -"semver@2 || 3 || 4 || 5", semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.3.5, semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.5, semver@^7.0.0, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -6359,20 +6336,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shelljs@0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== +shelljs@0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== dependencies: glob "^7.0.0" interpret "^1.0.0" rechoir "^0.6.2" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -6383,9 +6355,9 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-concat@^1.0.0: version "1.0.1" @@ -6393,9 +6365,9 @@ simple-concat@^1.0.0: integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^3.0.3, simple-get@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== dependencies: decompress-response "^4.2.0" once "^1.3.1" @@ -6421,12 +6393,12 @@ sonic-boom@^1.0.2: atomic-sleep "^1.0.0" flatstr "^1.0.12" -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-support@^0.5.17, source-map-support@~0.5.20: +source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -6512,9 +6484,9 @@ sprintf-js@~1.0.2: integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -6551,9 +6523,9 @@ strict-uri-encode@^2.0.0: integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= string-kit@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/string-kit/-/string-kit-0.16.0.tgz#63a1d7b7afd0d2b2214b6ab0d82040b2047d0676" - integrity sha512-xiJvm0KiJrOYDFzANh/LnMXEujnveaxcmspx9rg4r5qaIvex9b77h7fa6Ba+/0kEZXMvYcOS6Y7vJzK8lAUbUg== + version "0.16.1" + resolved "https://registry.yarnpkg.com/string-kit/-/string-kit-0.16.1.tgz#984ef9b08a9fa375af1dc8f1c58eb75c8a6f3594" + integrity sha512-LEwNbaW3iUZnfDIeUghvmxUoDnU6QClll/TFKENBMfFRZH481XijeLQPvhdNGIATVIunCXxjSJvVoFSBkfG1mg== string-similarity@^4.0.1: version "4.0.4" @@ -6587,12 +6559,12 @@ string-width@^2.1.0: strip-ansi "^4.0.0" string-width@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.0.1.tgz#0d8158335a6cfd8eb95da9b6b262ce314a036ffd" - integrity sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g== + version "5.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.0.tgz#5ab00980cfb29f43e736b113a120a73a0fb569d3" + integrity sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ== dependencies: + eastasianwidth "^0.2.0" emoji-regex "^9.2.2" - is-fullwidth-code-point "^4.0.0" strip-ansi "^7.0.1" string_decoder@^1.1.1: @@ -6688,7 +6660,7 @@ supports-color@8.1.1: dependencies: has-flag "^4.0.0" -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -6707,6 +6679,11 @@ supports-color@^9.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891" integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" @@ -6745,9 +6722,9 @@ temp-write@^4.0.0: uuid "^3.3.2" terminal-kit@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/terminal-kit/-/terminal-kit-2.3.0.tgz#ed8d7a7f1eee5efdcf994b67f712e4c2352f7387" - integrity sha512-Jyz6zm9r/h6brAv8205zhCcN+sUlMPjXqUSLPhcK4yFXWJ6maYvL8SykBWTjOg3YZ+kNU/MhNGIsWJja1rX7Ag== + version "2.4.0" + resolved "https://registry.yarnpkg.com/terminal-kit/-/terminal-kit-2.4.0.tgz#d572601ee3e25bcf1c05e223990436fce8f1a075" + integrity sha512-lQCKNFYCaVoFM23pcurnQ7wOnsz4u588JNu2sfNOnB8IU6Tl4vdOdHNe7bL2aIiB0kA7m94gS4VI0+3CRI1G/A== dependencies: "@cronvel/get-pixels" "^3.4.0" chroma-js "^2.1.2" @@ -6857,17 +6834,19 @@ to-regex-range@^5.0.1: is-number "^7.0.0" to-vfile@^7.0.0: - version "7.2.2" - resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-7.2.2.tgz#5976568397ef664bc8df210676d082478822afbf" - integrity sha512-7WL+coet3qyaYb5vrVrfLtOUHgNv9E1D5SIsyVKmHKcgZefy77WMQRk7FByqGKNInoHOlY6xkTGymo29AwjUKg== + version "7.2.3" + resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-7.2.3.tgz#4e54ad10878901703f1a956a33ba4f131c31eef7" + integrity sha512-QO0A9aE6Z/YkmQadJ0syxpmNXtcQiu0qAtCKYKD5cS3EfgfFTAXfgLX6AOaBrSfWSek5nfsMf3gBZ9KGVFcLuw== dependencies: is-buffer "^2.0.0" vfile "^5.1.0" -totalist@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-2.0.0.tgz#db6f1e19c0fa63e71339bbb8fba89653c18c7eec" - integrity sha512-+Y17F0YzxfACxTyjfhnJQEe7afPA0GSpYlFkl2VFMxYP7jshQf9gXV7cH47EfToBumFThfKBvfAcoUn6fdNeRQ== +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" tough-cookie@~2.5.0: version "2.5.0" @@ -6897,10 +6876,10 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.0.2.tgz#94a3aa9d5ce379fc561f6244905b3f36b7458d96" integrity sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w== -ts-node@^10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" - integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== +ts-node@^10.5.0: + version "10.5.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.5.0.tgz#618bef5854c1fbbedf5e31465cbb224a1d524ef9" + integrity sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw== dependencies: "@cspotcode/source-map-support" "0.7.0" "@tsconfig/node10" "^1.0.7" @@ -6913,18 +6892,7 @@ ts-node@^10.4.0: create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - yn "3.1.1" - -ts-node@^9: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== - dependencies: - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" + v8-compile-cache-lib "^3.0.0" yn "3.1.1" tsc-prog@^2.2.1: @@ -6937,16 +6905,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2, tslib@^2.3.1: +tslib@^2.1.0, tslib@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -7015,15 +6978,20 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^4.4.3, typescript@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" - integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +typescript@^4.4.3, typescript@^4.5.5: + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== uglify-js@^3.1.4: - version "3.14.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859" - integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ== + version "3.15.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.1.tgz#9403dc6fa5695a6172a91bc983ea39f0f7c9086d" + integrity sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ== + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== unified-args@^9.0.0: version "9.0.2" @@ -7041,15 +7009,15 @@ unified-args@^9.0.0: unified-engine "^9.0.0" unified-engine@^9.0.0: - version "9.0.4" - resolved "https://registry.yarnpkg.com/unified-engine/-/unified-engine-9.0.4.tgz#ee02b6a7f11e69a56f79cb8595065b8c3f02bda8" - integrity sha512-NFI+jC3DWZ23eBsWkOW2havz47DPG/DSyJEvBH+qA5cQHF6zlgiJYev7ksb/naOypZZ+cfhaCxCRo2BqrysYEw== + version "9.0.5" + resolved "https://registry.yarnpkg.com/unified-engine/-/unified-engine-9.0.5.tgz#7e417f2560942793ce41753ad53ee7428aaea40c" + integrity sha512-frQ6lUNlkTwVC0JELJqSSITpE7MLrLJqAWmDrUFj5Do6A4/3n6eX5Jyg8fhe4Dbwwh38spqUJd39FtRFG34QWg== dependencies: "@types/concat-stream" "^1.0.0" "@types/debug" "^4.0.0" "@types/is-empty" "^1.0.0" "@types/js-yaml" "^4.0.0" - "@types/node" "^16.0.0" + "@types/node" "^17.0.0" "@types/unist" "^2.0.0" concat-stream "^2.0.0" debug "^4.0.0" @@ -7061,7 +7029,7 @@ unified-engine@^9.0.0: is-plain-obj "^4.0.0" js-yaml "^4.0.0" load-plugin "^4.0.0" - parse-json "^5.0.0" + parse-json "^6.0.0" to-vfile "^7.0.0" trough "^2.0.0" unist-util-inspect "^7.0.0" @@ -7162,7 +7130,7 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -update-notifier@5.1.0: +update-notifier@5.1.0, update-notifier@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== @@ -7220,7 +7188,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@8.3.2, uuid@^8.3.0: +uuid@8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -7231,15 +7199,19 @@ uuid@^3.3.2, uuid@^3.3.3: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== uvu@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.2.tgz#c145e7f4b5becf80099cf22fd8a4a05f0112b2c0" - integrity sha512-m2hLe7I2eROhh+tm3WE5cTo/Cv3WQA7Oc9f7JB6uWv+/zVKvfAm53bMyOoGOSZeQ7Ov2Fu9pLhFr7p07bnT20w== + version "0.5.3" + resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.3.tgz#3d83c5bc1230f153451877bfc7f4aea2392219ae" + integrity sha512-brFwqA3FXzilmtnIyJ+CxdkInkY/i4ErvP7uV0DnUVxQcQ55reuHphorpF+tZoVHK2MniZ/VJzI7zJQoc9T9Yw== dependencies: dequal "^2.0.0" diff "^5.0.0" kleur "^4.0.3" sade "^1.7.3" - totalist "^2.0.0" + +v8-compile-cache-lib@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" + integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== v8-compile-cache@^2.0.3: version "2.3.0" @@ -7269,9 +7241,9 @@ verror@1.10.0: extsprintf "^1.2.0" vfile-message@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.0.2.tgz#db7eaebe7fecb853010f2ef1664427f52baf8f74" - integrity sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww== + version "3.1.0" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.0.tgz#5437035aa43185ff4b9210d32fada6c640e59143" + integrity sha512-4QJbBk+DkPEhBXq3f260xSaWtjE4gPKOfulzfMFF8ZNwaPZieWsg3iVlcmF04+eebzpcpeXOOFMfrYzJHVYg+g== dependencies: "@types/unist" "^2.0.0" unist-util-stringify-position "^3.0.0" @@ -7303,9 +7275,9 @@ vfile-statistics@^2.0.0: vfile-message "^3.0.0" vfile@^5.0.0, vfile@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.2.0.tgz#a32a646ff9251c274dbe8675644a39031025b369" - integrity sha512-ftCpb6pU8Jrzcqku8zE6N3Gi4/RkDhRwEXSWudzZzA2eEOn/cBpsfk9aulCUR+j1raRSAykYQap9u6j6rhUaCA== + version "5.3.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.0.tgz#4990c78cb3157005590ee8c930b71cd7fa6a006e" + integrity sha512-Tj44nY/48OQvarrE4FAjUfrv7GZOYzPbl5OD65HxVKwLJKMPU7zmfV8cCgCnzKWnSfYG2f3pxu+ALqs7j22xQQ== dependencies: "@types/unist" "^2.0.0" is-buffer "^2.0.0" @@ -7349,7 +7321,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@2.0.2, which@^2.0.1, which@^2.0.2: +which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -7394,10 +7366,10 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== +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@^6.2.0: version "6.2.0" @@ -7553,10 +7525,10 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^17.2.1, yargs@^17.3.0: - version "17.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.0.tgz#295c4ffd0eef148ef3e48f7a2e0f58d0e4f26b1c" - integrity sha512-GQl1pWyDoGptFPJx9b9L6kmR33TGusZvXIZUT+BOz9f7X2L94oeAskFYLEg/FkhV06zZPBYLvLZRWeYId29lew== +yargs@^17.2.1: + version "17.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" + integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== dependencies: cliui "^7.0.2" escalade "^3.1.1"