diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 236e23d30f65ac..c3527549e16af4 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -10,7 +10,7 @@ on: - cron: "*/5 * * * *" env: - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: startCI: diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 844a2a08ef6420..0f6fd639523cb0 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -3,7 +3,7 @@ name: "Commit messages adheres to guidelines at https://goo.gl/p2fr5Q" on: [pull_request] env: - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: lint-commit-message: diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index 25b7ea5a8cc4ae..9b8e99c98e5582 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -15,7 +15,7 @@ on: - cron: "*/5 * * * *" env: - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: commitQueue: diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index f628521bb7ea12..2ee6c8b5f19b77 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -4,19 +4,19 @@ on: pull_request: types: [opened, synchronize, reopened, ready_for_review] paths-ignore: - - 'doc/**' - - 'deps/**' + - '**.md' - 'benchmark/**' - - 'tools/**' + - 'deps/**' + - 'doc/**' push: branches: - master - main paths-ignore: - - 'doc/**' - - 'deps/**' + - '**.md' - 'benchmark/**' - - 'tools/**' + - 'deps/**' + - 'doc/**' env: PYTHON_VERSION: 3.9 @@ -44,6 +44,8 @@ jobs: run: NODE_V8_COVERAGE=coverage/tmp make test-cov -j2 V=1 TEST_CI_ARGS="-p dots" || exit 0 - name: Report JS run: npx c8 report --check-coverage + env: + NODE_OPTIONS: --max-old-space-size=8192 - name: Report C++ run: cd out && gcovr --gcov-exclude='.*\b(deps|usr|out|obj|cctest|embedding)\b' -v -r Release/obj.target --xml -o ../coverage/coverage-cxx.xml --root=$(cd ../ && pwd) # Clean temporary output from gcov and c8, so that it's not uploaded: diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index 5f515d1c24f2c7..0f0072bfe6c532 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -4,18 +4,20 @@ on: pull_request: types: [opened, synchronize, reopened, ready_for_review] paths-ignore: - - 'doc/**' - - 'deps/**' + - '**.md' - 'benchmark/**' + - 'deps/**' + - 'doc/**' - 'tools/**' push: branches: - master - main paths-ignore: - - 'doc/**' - - 'deps/**' + - '**.md' - 'benchmark/**' + - 'deps/**' + - 'doc/**' - 'tools/**' env: diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 3d8d66a1254920..e36a3fb5194125 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -6,7 +6,7 @@ on: - cron: "0 0 * * *" env: - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: build-lto: diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 6bdaee8d656c1d..987a38e56165fe 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -12,7 +12,7 @@ on: env: PYTHON_VERSION: 3.9 - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: lint-addon-docs: diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml index 89793e85953181..64f58f2e96f448 100644 --- a/.github/workflows/misc.yml +++ b/.github/workflows/misc.yml @@ -11,7 +11,7 @@ on: - v[0-9]+.x env: - NODE_VERSION: 14.x + NODE_VERSION: lts/* jobs: build-docs: diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml index 77839c314a569e..2762a08fa10bc8 100644 --- a/.github/workflows/test-asan.yml +++ b/.github/workflows/test-asan.yml @@ -9,10 +9,12 @@ on: - v[0-9]+.x-staging - v[0-9]+.x paths-ignore: + - '**.md' - 'doc/**' pull_request: types: [opened, synchronize, reopened, ready_for_review] paths-ignore: + - '**.md' - 'doc/**' env: diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index 686342f2f02081..adcacc9b99187c 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -4,6 +4,7 @@ on: pull_request: types: [opened, synchronize, reopened, ready_for_review] paths-ignore: + - '**.md' - 'doc/**' push: branches: @@ -13,6 +14,7 @@ on: - v[0-9]+.x-staging - v[0-9]+.x paths-ignore: + - '**.md' - 'doc/**' env: diff --git a/.mailmap b/.mailmap index 83c9c5cab55ce1..e53d49109038df 100644 --- a/.mailmap +++ b/.mailmap @@ -28,7 +28,7 @@ Andy Bettisworth Angel Stoyanov Anna Henningsen Anna Henningsen -Anna Magdalena Kedzierska AnnaMag +Anna Magdalena Kedzierska Antoine Amara Aria Stewart Arlo Breault @@ -50,7 +50,7 @@ Ben Noordhuis Ben Taber Benjamin Coe Benjamin Coe -Benjamin Fleischer Benjamin Fleischer +Benjamin Fleischer Benjamin Gruenbaum Benjamin Gruenbaum Benjamin Gruenbaum @@ -60,11 +60,11 @@ Bert Belder Bert Belder Beth Griggs Bidisha Pyne -bl-ue bl-ue <54780737+bl-ue@users.noreply.github.com> +bl-ue <54780737+bl-ue@users.noreply.github.com> Brad Decker Brad Larson Brandon Benvie -Brandon Kobel kobelb +Brandon Kobel Brendan Ashworth Brent Pendergraft Brian White @@ -89,7 +89,7 @@ Colin Ihrig Corey Martin Damien Simonin Feugas Dan Kaplun -Dan Williams Dan.Williams +Dan Williams Daniel Abrão Daniel Berger Daniel Bevenius @@ -99,8 +99,8 @@ Daniel Gröber Daniel Paulino Daniel Pihlström Daniel Wang -Daniel Wang firedfox -Danielle Adams Danielle Adams +Daniel Wang +Danielle Adams Danny Nemer Danny Nemer Darshan Sen @@ -115,7 +115,7 @@ DC Deepjyoti Mondal Domenic Denicola Domenic Denicola -Doug Wade doug.wade +Doug Wade Eduard Burtescu Einar Otto Stangvik Elliott Cable @@ -123,6 +123,9 @@ Eric Phetteplace Ernesto Salazar Erwin W. Ramadhan Eugene Obrezkov +Eugene Ostroukhov +Eugene Ostroukhov +Eugene Ostroukhov EungJun Yi Evan Larkin Evan Lucas @@ -138,17 +141,18 @@ Felix Geisendörfer Flandre Scarlet Florian Margaine Forrest L Norvell -Franziska Hinkelmann F. Hinkelmann +Franziska Hinkelmann Friedemann Altrock Fuji Goro Gabriel de Perthuis Gareth Ellis Garwah Lam +garygsc Geoffrey Bugaisky Gerhard Stöbich Gibson Fahnestock Gil Pedersen -Graham Fairweather Xotic750 +Graham Fairweather Greg Sabia Tucker Gregor Martynus Guy Bedford @@ -158,8 +162,8 @@ Hannes Magnusson Hendrik Schwalm Henry Chin Herbert Vojčík -himself65 -himself65 +himself65 +himself65 Hitesh Kanwathirtha Icer Liang Igor Savin @@ -169,12 +173,12 @@ Imran Iqbal Ionică Bizău Isaac Z. Schlueter Isaac Z. Schlueter -Isaac Z. Schlueter isaacs +Isaac Z. Schlueter Isuru Siriwardana Italo A. Casas Jackson Tian Jake Verbaten -Jamen Marzonie Jamen Marz +Jamen Marzonie James Beavers James Hartig James M Snell @@ -194,11 +198,11 @@ Johan Bergström Johan Dahlberg Johann Hofmann John Barboza -John Barboza jBarz +John Barboza John Gardner John McGuirk John Musgrave -Johnny Ray Austin Johnny Ray +Johnny Ray Austin Jon Tippens Jonas Pfenniger Jonathan Gourlay @@ -211,7 +215,7 @@ Josh Erickson Josh Hunter Joshua S. Weinstein Joyee Cheung -Joyee Cheung Joyee Cheung +Joyee Cheung Juan Sebastian Velez Posada Juan Soto Julien Gilli @@ -239,7 +243,7 @@ Koichi Kobayashi Kostiantyn Wandalen Kris Kowal Kyle Robinson Young -Lakshmi Swetha Gopireddy LAKSHMI SWETHA GOPIREDDY +Lakshmi Swetha Gopireddy Leeseean Chiu Luke Bayes Lydia Kats @@ -269,7 +273,7 @@ Matt Reed Matteo Collina Matthew Lye Matthew Turner -Matthias Bastian piepmatz +Matthias Bastian Maurice Hayward Michael Bernstein Michael Dawson @@ -297,10 +301,12 @@ Nicholas Kinsey Nick Soggin Nikolai Vavilov Nils Kuhnhenn -Nitzan Uziely Nitzan Uziely +Nitzan Uziely Noah Rose Ledesma Oluwaseun Omoyajowo Onne Gorter +Oscar Martinez +Paul Graham Paul Querna Pedro Lima Peng Lyu @@ -309,6 +315,7 @@ Peter Marton Peter Paugh Phillip Johnsen Prateek Singh +Qingyu Deng Rachel White Ratikesh Misra Ravindra Barthwal @@ -321,9 +328,12 @@ Reza Akhavan Ricardo Sánchez Gregorio Richard Lau Rick Olson +rickyes <0x19951125@gmail.com> +rickyes <0x19951125@gmail.com> Rob Adelmann Rob Adelmann -Robert Nagy Robert Nagy +Robert Nagy +Robin Drexler Rod Machen Roman Klauke Roman Reiss @@ -336,15 +346,17 @@ Ryan Dahl Ryan Emery Ryan Mahan Ryan Scheel -Saad Quadri saadq +Saad Quadri Sagir Khan Sakthipriyan Vairamani Sam Mikes Sam P Gallagher-Bishop Sam Roberts Sam Shull +Sam Shull Sam Shull -Samantha Sample = <=> +Samuel Attard +Samantha Sample <=> Sambasiva Suda San-Tai Hsu Santiago Gimeno @@ -354,9 +366,10 @@ Saúl Ibarra Corretgé Scott Blomquist Segu Riluvan Sergey Kryzhanovsky +Sergey Zelenov Shannen Saez Shaopeng Zhang -Shelley Vohr Shelley Vohr +Shelley Vohr Shigeki Ohtsu Shigeki Ohtsu Shivang Saxena @@ -366,7 +379,7 @@ Siddharth Mahendraker Simon Willison Siobhan O'Donovan Siyuan Gao -solebox solebox <5013box@gmail.com> +solebox <5013box@gmail.com> Sreepurna Jasti Sreepurna Jasti Stanislav Opichal @@ -378,14 +391,16 @@ Steve Mao Steven R. Loomis Stewart X Addison Suraiya Hameed -Suramya shah ss22ever +Suramya shah Surya Panikkal +Szymon Marczak <36894700+szmarczak@users.noreply.github.com> Tadashi SAWADA +Tadhg Creedon Taehee Kang Takahiro ANDO Tanuja-Sawant Tarun Batra -Taylor Woll taylor.woll +Taylor Woll Ted Young Teppei Sato Theotime Poisseau @@ -394,9 +409,11 @@ Thomas Lee Thomas Reggi Thomas Watson Tierney Cyren -Tierney Cyren &! (bitandbang) +Tierney Cyren Tim Caswell +Tim Costa Tim Price +Tim Ruffles Tim Smart Tim Smart Timothy Leverett @@ -407,7 +424,7 @@ TJ Holowaychuk TJ Holowaychuk Tobias Nießen Toby Farley -Toby Stableford toboid +Toby Stableford Todd Kennedy Tom Atkinson Tom Atkinson @@ -420,25 +437,30 @@ Tracy Hinds Travis Meisenheimer Trevor Burnham Trivikram Kamat <16024985+trivikr@users.noreply.github.com> +ttzztztz Tyler Larson -Ujjwal Sharma +Ujjwal Sharma +Ujjwal Sharma +Uttam Pawar Viktor Karpov Vincent Voyer Vladimir de Turckheim -Voltrex Voltrex <62040526+VoltrexMaster@users.noreply.github.com> +Voltrex <62040526+VoltrexMaster@users.noreply.github.com> vsemozhetbyt Wang Xinyong Wei-Wei Wu -Weijia Wang <381152119@qq.com> -Weijia Wang <381152119@qq.com> -Weijia Wang <381152119@qq.com> +Weijia Wang +Weijia Wang <381152119@qq.com> +Weijia Wang Will Hayslett Willi Eggeling Wilson Lin Wyatt Preul Xavier J Ortiz xiaoyu <306766053@qq.com> +Xu Meng Yael Hermon +ycjcl868 <45808948@qq.com> Yingchen Xue Yongsheng Zhang Yongsheng Zhang <17367077526@163.com> diff --git a/AUTHORS b/AUTHORS index d9ae717436d206..213c03ba9f32a8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -652,7 +652,7 @@ Ben Burns Julian Duque Teppei Sato Rudi Cilibrasi -Tim Ruffles +Tim Ruffles CGavrila Aleksey Smolenchuk Caitlin Potter @@ -995,6 +995,7 @@ Doug Wade Mohsen Marian Justin Sprigg +Eugene Ostroukhov Bryan Hughes Ehsan Akhgari Ingvar Stepanyan @@ -1204,7 +1205,7 @@ Daniel Pittman Ian White Chris Bystrek Christine Hong -Oscar Martinez +Oscar Martinez Aileen David Bradford stokingerl @@ -1254,7 +1255,7 @@ J Scott Chapman Erez Weiss Scott Smereka Fabrice Tatieze -Uttam Pawar +Uttam Pawar Ben Lugavere Punit Buch mark hughes @@ -1270,12 +1271,11 @@ amrios Chris Henney Yojan Shrestha Rodrigo Palma -Sam Shull Michael-Bryant Choa CodeVana Daniel Sims Diego Paez -Paul Graham +Paul Graham Jared Young vazina robertson Bruce Lai @@ -1324,7 +1324,6 @@ malen Kailean Courtney Fumiya KARASAWA John Barboza -Paul Graham Nate Chris Story Matthew Garrett @@ -1481,7 +1480,6 @@ Tony Rice Olivier Martin jeyanthinath Aditya Anand -Oscar Martinez cool88 Steven Lehn Łukasz Szewczak @@ -1543,7 +1541,7 @@ lena Azard <330815461@qq.com> Ezequiel Garcia Kyle Farnung -Weijia Wang <381152119@qq.com> +Weijia Wang Nataly Shrits Jaime Bernardo Natanael Log @@ -1620,7 +1618,6 @@ Mandeep Singh Prakash Palaniappan Keita Akutsu Michael Albert -Eugene Ostroukhov Vishal Bisht Griffith Tchenpan Oky Antoro @@ -1664,7 +1661,7 @@ Miguel Martins Yury Popov George Bezerra Benjamin Coe -Tim Costa +Tim Costa Rahul Mishra Damien O'Reilly Tuan Anh Tran @@ -2116,7 +2113,7 @@ dustinnewman98 Oluwaseun Omoyajowo Wilson Lin Eric Bickle -Ujjwal Sharma +Ujjwal Sharma Wei-Wei Wu Prateek Singh Ken Lin @@ -2270,7 +2267,6 @@ prayag21 <10997858+prayag21@users.noreply.github.com> Bruno Pinho Anto Aravinth Helio Frota <00hf11@gmail.com> -Tim Ruffles Jacob Page sagulati conectado @@ -2498,14 +2494,14 @@ Jerome Covington Rob Reynolds warnerp18 chux0519 -Tadhg Creedon +Tadhg Creedon Petar Dodev mzucker Morgan Roderick Remy Parzinski Roland Broekema Florin-Daniel BÎLBÎE -Robin Drexler +Robin Drexler ZauberNerd G. Carcaci Jackson Chui <14085209+haiXchuus@users.noreply.github.com> @@ -2582,7 +2578,6 @@ rahulshuklab4u gengjiawen Maya Anilson Mrityunjoy Saha -Robin Drexler Prabu Subra Abhishek Dixit Sarath Govind K K @@ -2620,7 +2615,6 @@ grimrose timothy searcy nakashima /Jesse -Tadhg Creedon exoego sigwyg pastak @@ -2672,7 +2666,6 @@ Amit Zur Thang Tran Kai Abhishek Agarwal -Uttam Pawar Jon Kunkee Mukul Khanna Jarrod Connolly @@ -2681,7 +2674,7 @@ Alexander Sattelmaier Avi ד Thomas Aymen Naghmouchi -himself65 +himself65 Geir Hauge Patrick Gansterer Nicolas Moteau @@ -2731,7 +2724,6 @@ imhype <543717080@qq.com> ptaylor Boxuan Li Aditya Pratap Singh -Eugene Ostroukhov Preveen Padmanabhan Benjamin Ki Daniel Nalborczyk @@ -2790,13 +2782,11 @@ Juan Roa Ivan Villa Caleb ツ Everett Miken -Eugene Ostroukhov Gabriela Niño Mike MacCana Tim Baverstock Walle Cyril -Xu Meng -Samuel Attard +Xu Meng Ben L. Titzer Ojasvi Monga Shajan Jacob @@ -2846,7 +2836,7 @@ Javier Ledezma Marian Rusnak <4215517+marian-r@users.noreply.github.com> Jenia Anton Gerasimov -rickyes +rickyes <0x19951125@gmail.com> Simon A. Eugster TATSUNO Yasuhiro Robert Jensen @@ -2892,7 +2882,6 @@ Albert Wang Kenza Houmani mkdorff xefimx -garygsc Susana Ferreira Xavier Redondo Duncan Healy @@ -2962,7 +2951,6 @@ Rosen Penev Jeremy Albright Giovanni Campagna Donggeon Lim -Tim Costa rene.herrmann Derek Lewis Kirill Ponomarev @@ -3015,13 +3003,11 @@ Andrew Neitsch RamanandPatil forfun414 David Gilbertson -Sergey Zelenov Eric Bickle Joe Pea ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Mateusz Krawczuk Jonathan MERCIER -Ujjwal Sharma Jichan Hassaan Pasha Eric Dobbertin @@ -3034,7 +3020,6 @@ Sk Sajidul Kadir Bartlomiej Brzozowski Saajan Yash Ladha -Xu Meng Alex R Hachimi Aa (Sfeir) Daniel Estiven Rico Posada @@ -3083,7 +3068,6 @@ Ben Bucksch Eli Schwartz Maciej Kacper Jagiełło Tom Nagle -rickyes sapics Sagar Jadhav Dennis Ameling @@ -3175,10 +3159,8 @@ krank2me masx200 <34191203+masx200@users.noreply.github.com> Baruch Odem (Rothkoff) Mattias Runge-Broberg -Szymon Marczak <36894700+szmarczak@users.noreply.github.com> Dmitry Semigradsky Ole André Vadla Ravnås -rickyes <0x19951125@gmail.com> Aleksandr Krutko Brian Ingenito <28159742+bingenito@users.noreply.github.com> FeelyChau @@ -3227,7 +3209,7 @@ Ian Storm Taylor Carlos Fuentes Tyler Ang-Wanek Matthew Mario Di Pasquale -ttzztztz +ttzztztz Romuald Brillout Dave Cardwell Akash Negi <55234838+NegiAkash890@users.noreply.github.com> @@ -3235,7 +3217,7 @@ James Addison Fabian Cook Kalvin Vasconcellos marsonya -Qingyu Deng +Qingyu Deng Matin Zadehdolatabad Daniel Clark Sajal Khandelwal @@ -3244,7 +3226,6 @@ Utku Gultopu Jay Tailor <60511316+JayvaScript@users.noreply.github.com> Greg Ziskind Dan Čermák -ttzztztz Vít Ondruch humanwebpl <58517331+humanwebpl@users.noreply.github.com> Dawid Rusnak @@ -3267,7 +3248,7 @@ Anu Pasumarthy HiroyukiYagihashi Arkerone Voltrex -ycjcl868 +ycjcl868 <45808948@qq.com> Serkan Özel Ferdi eladkeyshawn @@ -3308,8 +3289,6 @@ bl-ue npm-robot Shaun Keys Simone Busoli -ycjcl868 <45808948@qq.com> -Qingyu Deng Derevianchenko Maksym <32910350+maks-white@users.noreply.github.com> RA80533 <32469082+RA80533@users.noreply.github.com> Mao Wtm @@ -3328,5 +3307,10 @@ LitoMore nerdthatnoonelikes Nikita Rykov <40735471+angrymouse@users.noreply.github.com> Benjamin Mayr +Lew Gordon +Mestery +Himadri Ganguly +Howie Zhao +Luan Devecchi # Generated by tools/update-authors.js diff --git a/BUILDING.md b/BUILDING.md index 6f54601b5a078c..06cfaff6052bb4 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -113,8 +113,8 @@ platforms. This is true regardless of entries in the table below. | Windows | x86 (native) | >= Windows 8.1/2012 R2 | Tier 1 (running) / Experimental (compiling) [6](#fn6) | | | Windows | x64, x86 | Windows Server 2012 (not R2) | Experimental | | | Windows | arm64 | >= Windows 10 | Tier 2 (compiling) / Experimental (running) | | -| macOS | x64 | >= 10.13 | Tier 1 | | -| macOS | arm64 | >= 11 | Experimental | | +| macOS | x64 | >= 10.13 | Tier 1 | For notes about compilation see [8](#fn8) | +| macOS | arm64 | >= 11 | Tier 1 | | | SmartOS | x64 | >= 18 | Tier 2 | | | AIX | ppc64be >=power7 | >= 7.2 TL04 | Tier 2 | | | FreeBSD | x64 | >= 11 | Experimental | Downgraded as of Node.js 12 [7](#fn7) | @@ -155,6 +155,10 @@ may not be possible. FreeBSD 12.1 upgrades to 8.0.1. Other Clang/LLVM versions are available via the system's package manager, including Clang 9.0. +8: Our macOS x64 Binaries are compiled with 10.13 as a target. +However there is no guarantee compiling on 10.13 will work as Xcode11 is +required to compile. + ### Supported toolchains Depending on the host platform, the selection of toolchains may vary. diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c91f6cf419705..1ba3b059ef9b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,8 @@ release. -16.6.2
+16.7.0
+16.6.2
16.6.1
16.6.0
16.5.0
diff --git a/LICENSE b/LICENSE index 82a9eafafe50d2..29bd53a3610f89 100644 --- a/LICENSE +++ b/LICENSE @@ -1584,3 +1584,22 @@ The externally maintained libraries used by Node.js are: OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + +- node-fs-extra, located at lib/internal/fs/cp, is licensed as follows: + """ + (The MIT License) + + Copyright (c) 2011-2017 JP Richardson + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files + (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS + OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + """ diff --git a/README.md b/README.md index e4824bc84471c7..4408ef5126e709 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ For information about the governance of the Node.js project, see * [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> (he/him) * [codebytere](https://github.com/codebytere) - -**Shelley Vohr** <codebytere@gmail.com> (she/her) +**Shelley Vohr** <shelley.vohr@gmail.com> (she/her) * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> (he/him) * [danielleadams](https://github.com/danielleadams) - @@ -288,7 +288,7 @@ For information about the governance of the Node.js project, see * [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> (he/him) * [codebytere](https://github.com/codebytere) - -**Shelley Vohr** <codebytere@gmail.com> (she/her) +**Shelley Vohr** <shelley.vohr@gmail.com> (she/her) * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> (he/him) * [danielleadams](https://github.com/danielleadams) - @@ -319,8 +319,6 @@ For information about the governance of the Node.js project, see **Gerhard Stöbich** <deb2001-github@yahoo.de> (he/they) * [gabrielschulhof](https://github.com/gabrielschulhof) - **Gabriel Schulhof** <gabrielschulhof@gmail.com> -* [gdams](https://github.com/gdams) - -**George Adams** <george.adams@microsoft.com> (he/him) * [geek](https://github.com/geek) - **Wyatt Preul** <wpreul@gmail.com> * [gengjiawen](https://github.com/gengjiawen) - @@ -494,6 +492,8 @@ For information about the governance of the Node.js project, see **Alexander Makarenko** <estliberitas@gmail.com> * [firedfox](https://github.com/firedfox) - **Daniel Wang** <wangyang0123@gmail.com> +* [gdams](https://github.com/gdams) - +**George Adams** <george.adams@microsoft.com> (he/him) * [gibfahn](https://github.com/gibfahn) - **Gibson Fahnestock** <gibfahn@gmail.com> (he/him) * [glentiki](https://github.com/glentiki) - diff --git a/benchmark/perf_hooks/usertiming.js b/benchmark/perf_hooks/usertiming.js index ae797351ad78cc..24a53a116785df 100644 --- a/benchmark/perf_hooks/usertiming.js +++ b/benchmark/perf_hooks/usertiming.js @@ -8,24 +8,27 @@ const { } = require('perf_hooks'); const bench = common.createBenchmark(main, { - n: [1e5] + n: [1e5], + observe: ['all', 'measure'], }); function test() { performance.mark('a'); - setImmediate(() => { - performance.mark('b'); - performance.measure('a to b', 'a', 'b'); - }); + performance.mark('b'); + performance.measure('a to b', 'a', 'b'); } -function main({ n }) { +function main({ n, observe }) { + const entryTypes = observe === 'all' ? + [ 'mark', 'measure' ] : + [ observe ]; const obs = new PerformanceObserver(() => { bench.end(n); }); - obs.observe({ entryTypes: ['measure'], buffered: true }); + obs.observe({ entryTypes, buffered: true }); bench.start(); - for (let i = 0; i < n; i++) + performance.mark('start'); + for (let i = 0; i < 1e5; i++) test(); } diff --git a/common.gypi b/common.gypi index d4f1d425f83958..fcd1cebeb56007 100644 --- a/common.gypi +++ b/common.gypi @@ -356,7 +356,10 @@ ], }], ['v8_enable_pointer_compression == 1', { - 'defines': ['V8_COMPRESS_POINTERS'], + 'defines': [ + 'V8_COMPRESS_POINTERS', + 'V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE', + ], }], ['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', { 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'], diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index 045b7702d958de..7be85aba980e40 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -2,6 +2,7 @@ A. Hauptmann Aaron Bieber Alan Gutierrez Andrius Bentkus +Andy Fiddaman Bert Belder Bert Belder Bert Belder @@ -10,6 +11,8 @@ Brian White Brian White Caleb James DeLisle Christoph Iserlohn +Darshan Sen +David Carlier Devchandra Meetei Leishangthem Fedor Indutny Frank Denis @@ -53,4 +56,5 @@ gengjiawen jBarz jBarz ptlomholt +tjarlama <59913901+tjarlama@users.noreply.github.com> zlargon diff --git a/deps/uv/.readthedocs.yaml b/deps/uv/.readthedocs.yaml new file mode 100644 index 00000000000000..e53b9f3e84be0a --- /dev/null +++ b/deps/uv/.readthedocs.yaml @@ -0,0 +1,11 @@ +version: 2 + +sphinx: + builder: html + configuration: null + fail_on_warning: false + +python: + version: 3.8 + install: + - requirements: docs/requirements.txt diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 9f327af9f8303f..741bcc708cb5e0 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -114,7 +114,6 @@ Dylan Cali Austin Foxley Benjamin Saunders Geoffry Song -Rasmus Christian Pedersen William Light Oleg Efimov Lars Gierth @@ -123,7 +122,6 @@ Justin Venus Kristian Evensen Linus Mårtensson Navaneeth Kedaram Nambiathan -Yorkie StarWing thierry-FreeBSD Isaiah Norton @@ -459,3 +457,25 @@ schamberg97 <50446906+schamberg97@users.noreply.github.com> Bob Weinand Issam E. Maghni Juan Pablo Canepa +Shuowang (Wayne) Zhang +Ondřej Surý +Juan José Arboleda +Zhao Zhili +Brandon Cheng +Matvii Hodovaniuk +Hayden +yiyuaner +bbara +SeverinLeonhardt +Andy Fiddaman +Romain Roffé +Eagle Liang +Ricky Zhou +Simon Kissane +James M Snell +Ali Mohammad Pur +Erkhes N <71805796+rexes-ND@users.noreply.github.com> +Joshua M. Clulow +Guilherme Íscaro +Martin Storsjö +Claes Nästén diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index c8e881d18f503e..148d0e68992c83 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -34,7 +34,8 @@ option(ASAN "Enable AddressSanitizer (ASan)" OFF) if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") add_definitions(-D__ASAN__=1) set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") - set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address") endif() # Compiler check @@ -209,10 +210,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android") src/unix/pthread-fixes.c src/unix/random-getentropy.c src/unix/random-getrandom.c - src/unix/random-sysctl-linux.c) + src/unix/random-sysctl-linux.c + src/unix/epoll.c) endif() -if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390") +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux") list(APPEND uv_sources src/unix/proctitle.c) endif() @@ -253,7 +255,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-syscalls.c src/unix/procfs-exepath.c src/unix/random-getrandom.c - src/unix/random-sysctl-linux.c) + src/unix/random-sysctl-linux.c + src/unix/epoll.c) endif() if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") @@ -266,9 +269,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") endif() if(CMAKE_SYSTEM_NAME STREQUAL "OS390") - list(APPEND uv_defines PATH_MAX=255) + enable_language(CXX) + list(APPEND uv_defines PATH_MAX=1024) list(APPEND uv_defines _AE_BIMODAL) list(APPEND uv_defines _ALL_SOURCE) + list(APPEND uv_defines _ENHANCED_ASCII_EXT=0xFFFFFFFF) list(APPEND uv_defines _ISOC99_SOURCE) list(APPEND uv_defines _LARGE_TIME_API) list(APPEND uv_defines _OPEN_MSGQ_EXT) @@ -279,14 +284,31 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390") list(APPEND uv_defines _UNIX03_SOURCE) list(APPEND uv_defines _UNIX03_THREADS) list(APPEND uv_defines _UNIX03_WITHDRAWN) + list(APPEND uv_defines _XOPEN_SOURCE=600) list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED) list(APPEND uv_sources src/unix/pthread-fixes.c src/unix/os390.c - src/unix/os390-syscalls.c) - list(APPEND uv_cflags -Wc,DLL -Wc,exportall -Wc,xplink) - list(APPEND uv_libraries -Wl,xplink) - list(APPEND uv_test_libraries -Wl,xplink) + src/unix/os390-syscalls.c + src/unix/os390-proctitle.c) + list(APPEND uv_cflags + -q64 + -qascii + -qexportall + -qgonumber + -qlongname + -qlibansi + -qfloat=IEEE + -qtune=10 + -qarch=10 + -qasm + -qasmlib=sys1.maclib:sys1.modgen) + find_library(ZOSLIB + NAMES zoslib + PATHS ${ZOSLIB_DIR} + PATH_SUFFIXES lib + ) + list(APPEND uv_libraries ${ZOSLIB}) endif() if(CMAKE_SYSTEM_NAME STREQUAL "OS400") @@ -303,9 +325,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS400") endif() if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") - list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500) + list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT) list(APPEND uv_libraries kstat nsl sendfile socket) - list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c) + list(APPEND uv_sources + src/unix/no-proctitle.c + src/unix/sunos.c) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") @@ -349,6 +373,10 @@ target_include_directories(uv $ PRIVATE $) +if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + target_include_directories(uv PUBLIC $) + set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX) +endif() target_link_libraries(uv ${uv_libraries}) add_library(uv_a STATIC ${uv_sources}) @@ -360,6 +388,10 @@ target_include_directories(uv_a $ PRIVATE $) +if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + target_include_directories(uv_a PUBLIC $) + set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX) +endif() target_link_libraries(uv_a ${uv_libraries}) if(LIBUV_BUILD_TESTS) @@ -457,6 +489,9 @@ if(LIBUV_BUILD_TESTS) test/test-metrics.c test/test-multiple-listen.c test/test-mutexes.c + test/test-not-readable-nor-writable-on-read-error.c + test/test-not-readable-on-eof.c + test/test-not-writable-after-shutdown.c test/test-osx-select.c test/test-pass-always.c test/test-ping-pong.c @@ -489,6 +524,7 @@ if(LIBUV_BUILD_TESTS) test/test-semaphore.c test/test-shutdown-close.c test/test-shutdown-eof.c + test/test-shutdown-simultaneous.c test/test-shutdown-twice.c test/test-signal-multiple-loops.c test/test-signal-pending-on-close.c @@ -582,6 +618,11 @@ if(LIBUV_BUILD_TESTS) add_test(NAME uv_test_a COMMAND uv_run_tests_a WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + set_target_properties(uv_run_benchmarks_a PROPERTIES LINKER_LANGUAGE CXX) + set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX) + set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX) + endif() endif() if(UNIX OR MINGW) diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md index b0abe3b40eaa25..d37c51d6363856 100644 --- a/deps/uv/CONTRIBUTING.md +++ b/deps/uv/CONTRIBUTING.md @@ -23,11 +23,11 @@ The stable branch is effectively frozen; patches that change the libuv API/ABI or affect the run-time behavior of applications get rejected. In case of doubt, open an issue in the [issue tracker][], post your question -to the [libuv mailing list], or contact one of [project maintainers][] on [IRC][]. +to the [libuv discussions forum], or message the [libuv mailing list]. -Especially do so if you plan to work on something big. Nothing is more -frustrating than seeing your hard work go to waste because your vision -does not align with that of a project maintainers. +Especially do so if you plan to work on something big. Nothing is more +frustrating than seeing your hard work go to waste because your vision does not +align with that of the [project maintainers]. ### BRANCH @@ -166,6 +166,6 @@ not send out notifications when you add commits. [issue tracker]: https://github.com/libuv/libuv/issues [libuv mailing list]: http://groups.google.com/group/libuv -[IRC]: http://webchat.freenode.net/?channels=libuv +[libuv discussions forum]: https://github.com/libuv/libuv/discussions [Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html [project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index d0eaf9fe34a20f..4f2a4bc91dd0d0 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,158 @@ +2021.07.21, Version 1.42.0 (Stable) + +Changes since version 1.41.0: + +* doc: fix code highlighting (Darshan Sen) + +* test: move to ASSERT_NULL and ASSERT_NOT_NULL test macros (tjarlama) + +* zos: build in ascii code page (Shuowang (Wayne) Zhang) + +* zos: don't use nanosecond timestamp fields (Shuowang (Wayne) Zhang) + +* zos: introduce zoslib (Shuowang (Wayne) Zhang) + +* zos: use strnlen() from zoslib (Shuowang (Wayne) Zhang) + +* zos: use nanosleep() from zoslib (Shuowang (Wayne) Zhang) + +* zos: use __getargv() from zoslib to get exe path (Shuowang (Wayne) Zhang) + +* zos: treat __rfim_utok as binary (Shuowang (Wayne) Zhang) + +* zos: use execvpe() to set environ explictly (Shuowang (Wayne) Zhang) + +* zos: use custom proctitle implementation (Shuowang (Wayne) Zhang) + +* doc: add instructions for building on z/OS (Shuowang (Wayne) Zhang) + +* linux,udp: enable full ICMP error reporting (Ondřej Surý) + +* test: fix test-udp-send-unreachable (Ondřej Surý) + +* include: fix typo in documentation (Tobias Nießen) + +* chore: use for(;;) instead of while (Yash Ladha) + +* test: remove string + int warning on udp-pummel (Juan José Arboleda) + +* cmake: fix linker flags (Zhao Zhili) + +* test: fix stack-use-after-scope (Zhao Zhili) + +* unix: expose thread_stack_size() internally (Brandon Cheng) + +* darwin: use RLIMIT_STACK for fsevents pthread (Brandon Cheng) + +* darwin: abort on pthread_attr_init fail (Brandon Cheng) + +* benchmark: remove unreachable code (Matvii Hodovaniuk) + +* macos: fix memleaks in uv__get_cpu_speed (George Zhao) + +* Make Thread Sanitizer aware of file descriptor close in uv__close() (Ondřej + Surý) + +* darwin: fix iOS compilation and functionality (Hayden) + +* linux: work around copy_file_range() cephfs bug (Ben Noordhuis) + +* zos: implement uv_get_constrained_memory() (Shuowang (Wayne) Zhang) + +* zos: fix uv_get_free_memory() (Shuowang (Wayne) Zhang) + +* zos: use CVTRLSTG to get total memory accurately (Shuowang (Wayne) Zhang) + +* ibmi: Handle interface names longer than 10 chars (Kevin Adler) + +* docs: update read-the-docs version of sphinx (Jameson Nash) + +* unix: refactor uv_try_write (twosee) + +* linux-core: add proper divide by zero assert (yiyuaner) + +* misc: remove unnecessary _GNU_SOURCE macros (Darshan Sen) + +* test: log to stdout to conform TAP spec (bbara) + +* win,fs: fix C4090 warning with MSVC (SeverinLeonhardt) + +* build: some systems provide dlopen() in libc (Andy Fiddaman) + +* include: add EOVERFLOW status code mapping (Darshan Sen) + +* unix,fs: use uv__load_relaxed and uv__store_relaxed (Darshan Sen) + +* win: fix string encoding issue of uv_os_gethostname (Eagle Liang) + +* unix,process: add uv__write_errno helper function (Ricky Zhou) + +* Re-merge "unix,stream: clear read/write states on close/eof" (Jameson Nash) + +* unix,core: fix errno handling in uv__getpwuid_r (Darshan Sen) + +* errors: map ESOCKTNOSUPPORT errno (Ryan Liptak) + +* doc: uv_read_stop always succeeds (Simon Kissane) + +* inet: fix inconsistent return value of inet_ntop6 (twosee) + +* darwin: fix -Wsometimes-uninitialized warning (twosee) + +* stream: introduce uv_try_write2 function (twosee) + +* poll,win: UV_PRIORITIZED option should not assert (twosee) + +* src: DragonFlyBSD has mmsghdr struct too (David Carlier) + +* cleanup,win: Remove _WIN32 guards on threadpool (James M Snell) + +* freebsd: fix an incompatible pointer type warning (Darshan Sen) + +* core: Correct the conditionals for {cloexec,nonblock}_ioctl (Ali Mohammad + Pur) + +* win,tcp: make uv_close work more like unix (Jameson Nash) + +* doc: more accurate list of valid send_handle's (twosee) + +* win,tcp: translate system errors correctly (twosee) + +* unix: implement cpu_relax() on ppc64 (Ben Noordhuis) + +* docs: move list of project links under PR control (Jameson Nash) + +* test: wrong pointer arithmetic multiplier (Erkhes N) + +* doc: switch discussion forum to github (Jameson Nash) + +* idna: fix OOB read in punycode decoder (Ben Noordhuis) + +* build: make sure -fvisibility=hidden is set (Santiago Gimeno) + +* illumos: event ports to epoll (tjarlama) + +* illumos,tty: UV_TTY_MODE_IO waits for 4 bytes (Joshua M. Clulow) + +* doc: add vtjnash GPG ID (Jameson Nash) + +* linux: read CPU model information on ppc (Richard Lau) + +* darwin: fix uv_barrier race condition (Guilherme Íscaro) + +* unix,stream: fix loop hang after uv_shutdown (Jameson Nash) + +* doc,udp: note that suggested_size is 1 max-sized dgram (Ryan Liptak) + +* mingw: fix building for ARM/AArch64 (Martin Storsjö) + +* unix: strnlen is not available on Solaris 10 (Claes Nästén) + +* sunos: restore use of event ports (Andy Fiddaman) + +* sunos,cmake: use thread-safe errno (Andy Fiddaman) + + 2021.02.14, Version 1.41.0 (Stable), 1dff88e5161cba5c59276d2070d2e304e4dcb242 Changes since version 1.40.0: diff --git a/deps/uv/LINKS.md b/deps/uv/LINKS.md new file mode 100644 index 00000000000000..b8204e56e160d2 --- /dev/null +++ b/deps/uv/LINKS.md @@ -0,0 +1,101 @@ +### Apps / VM +* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities. +* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine +* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11) +* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software +* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps. +* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol. +* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included. +* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server. +* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2. +* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv. +* [Julia](http://julialang.org/): Scientific computing programming language +* [Kestrel](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet)) +* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver +* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release +* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js +* [libstorj](https://github.com/Storj/libstorj): Library for interacting with Storj network +* [libuv_message_framing](https://github.com/litesync/libuv_message_framing) Message-based communication for libuv +* [luaw](https://github.com/raksoras/luaw): Lua web server backed by libuv +* [Luvit](http://luvit.io): Node.JS for the Lua Inventor +* [mo](https://github.com/wehu/mo): Scheme (guile) + libuv runtime +* [MoarVM](https://github.com/MoarVM/MoarVM): a VM for [Rakudo](http://rakudo.org/) [Raku](http://raku.org) +* [Mysocks](https://github.com/zhou0/mysocks): a cross-platform [Shadowsocks](https://shadowsocks.org) client +* [mediasoup](http://mediasoup.org): Powerful WebRTC SFU for Node.js +* [Neovim](https://neovim.io/): A major refactor of Vim. +* [node9](https://github.com/jvburnes/node9): A portable, hybrid, distributed OS based on Inferno, LuaJIT and Libuv +* [node.js](http://www.nodejs.org/): Javascript (using Google's V8) + libuv +* [node.native](https://github.com/d5/node.native): node.js-like API for C++11 +* [nodeuv](https://github.com/nodeuv): An organization with several c++ wrappers for libs which are used in node.js. +* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js +* [pilight](https://www.pilight.org/): home automation ("domotica") +* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT +* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime +* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension +* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings +* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition +* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server. +* [Trevi](https://github.com/Yoseob/Trevi): A powerful Swift Web Application Server Framework Project +* [Urbit](http://urbit.org): runtime +* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication +* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv +* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules + +### Other +* [libtuv](https://github.com/Samsung/libtuv): libuv fork for IoT and embedded systems + +### Bindings +* [Ring](http://ring-lang.net) + * [RingLibuv](http://ring-lang.sourceforge.net/doc1.7/libuv.html) +* Ruby + * [libuv](https://github.com/cotag/libuv) + * [uvrb](https://github.com/avalanche123/uvrb) + * [ruv](https://github.com/aq1018/ruv) + * [rbuv](https://github.com/rbuv/rbuv) + * [mruby-uv](https://github.com/mattn/mruby-uv): mruby binding +* Lua + * [luv](https://github.com/creationix/luv) + * [lev](https://github.com/connectFree/lev) + * [lluv](https://github.com/moteus/lua-lluv) +* C++11 + * [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv` +* C++17 + * [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++. +* Python + * [Pyuv](https://github.com/saghul/pyuv) + * [uvloop](https://github.com/MagicStack/uvloop) - Ultra fast asyncio event loop. + * [gevent](http://www.gevent.org) - Coroutine-based concurrency library for Python +* C# + * [NetUV](http://github.com/StormHub/NetUV) + * [LibuvSharp](http://github.com/txdv/LibuvSharp) +* Perl 5 + * [UV](https://metacpan.org/pod/UV) +* [Raku](https://raku.org/) + * [MoarVM](https://github.com/MoarVM/MoarVM) [uses](http://6guts.wordpress.com/2013/05/31/moarvm-a-virtual-machine-for-nqp-and-rakudo/) libuv +* PHP + * [php-uv](https://github.com/bwoebi/php-uv) +* Go + * [go-uv](https://github.com/mattn/go-uv) +* OCaml + * [luv](https://github.com/aantron/luv) + * [uwt](https://github.com/fdopen/uwt) +* ooc + * [ooc-uv](https://github.com/nddrylliog/ooc-uv) +* dylan + * [uv-dylan](https://github.com/waywardmonkeys/uv-dylan) +* R + * [httpuv](https://github.com/rstudio/httpuv): HTTP and WebSocket server library for R + * [fs](https://fs.r-lib.org/): Cross-platform file system operations +* Java + * [libuv-java](https://java.net/projects/avatar-js/sources/libuv-java/show): Java bindings +* Nim + * [nimuv](https://github.com/2vg/nimuv): Nim bindings +* Lisp + * [cl-libuv](https://github.com/orthecreedence/cl-libuv) Common Lisp bindings + * [cl-async](https://github.com/orthecreedence/cl-async) Common Lisp async abstraction on top of cl-libuv +* [Céu](http://www.ceu-lang.org) + * [Céu-libuv](https://github.com/fsantanna/ceu-libuv) +* Delphi + * [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem +* Haskell + * [Z.Haskell](https://z.haskell.world) diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md index 268251e615a13d..fb7e5ef34172c5 100644 --- a/deps/uv/MAINTAINERS.md +++ b/deps/uv/MAINTAINERS.md @@ -16,6 +16,7 @@ libuv is currently managed by the following individuals: * **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq)) - GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere) * **Jameson Nash** ([@vtjnash](https://github.com/vtjnash)) + - GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash) * **John Barboza** ([@jbarz](https://github.com/jbarz)) * **Kaoru Takanashi** ([@erw7](https://github.com/erw7)) - GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7) diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index e8bab4963dda78..5830003c1e0736 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -206,6 +206,9 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-metrics.c \ test/test-multiple-listen.c \ test/test-mutexes.c \ + test/test-not-readable-nor-writable-on-read-error.c \ + test/test-not-readable-on-eof.c \ + test/test-not-writable-after-shutdown.c \ test/test-osx-select.c \ test/test-pass-always.c \ test/test-ping-pong.c \ @@ -238,6 +241,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-semaphore.c \ test/test-shutdown-close.c \ test/test-shutdown-eof.c \ + test/test-shutdown-simultaneous.c \ test/test-shutdown-twice.c \ test/test-signal-multiple-loops.c \ test/test-signal-pending-on-close.c \ @@ -388,7 +392,8 @@ libuv_la_CFLAGS += -D_GNU_SOURCE libuv_la_SOURCES += src/unix/android-ifaddrs.c \ src/unix/pthread-fixes.c \ src/unix/random-getrandom.c \ - src/unix/random-sysctl-linux.c + src/unix/random-sysctl-linux.c \ + src/unix/epoll.c endif if CYGWIN @@ -469,7 +474,8 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/procfs-exepath.c \ src/unix/proctitle.c \ src/unix/random-getrandom.c \ - src/unix/random-sysctl-linux.c + src/unix/random-sysctl-linux.c \ + src/unix/epoll.c test_run_tests_LDFLAGS += -lutil endif diff --git a/deps/uv/README.md b/deps/uv/README.md index f6c73709cc5b82..a9a8a9d1179e2f 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -5,7 +5,7 @@ libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by [Node.js][], but it's also used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/), -[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/wiki/Projects-that-use-libuv). +[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md). ## Feature highlights @@ -48,9 +48,8 @@ The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-do ## Community - * [Support](https://github.com/libuv/help) + * [Support](https://github.com/libuv/libuv/discussions) * [Mailing list](http://groups.google.com/group/libuv) - * [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4) ## Documentation @@ -308,6 +307,13 @@ describes the package in more detail. ### z/OS Notes +z/OS compilation requires [ZOSLIB](https://github.com/ibmruntimes/zoslib) to be installed. When building with [CMake][], use the flag `-DZOSLIB_DIR` to specify the path to [ZOSLIB](https://github.com/ibmruntimes/zoslib): + +```bash +$ (cd build && cmake .. -DBUILD_TESTING=ON -DZOSLIB_DIR=/path/to/zoslib) +$ cmake --build build +``` + z/OS creates System V semaphores and message queues. These persist on the system after the process terminates unless the event loop is closed. diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 4bdc7fd3f532b8..1fbb5c8c822f41 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.41.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.42.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -24,7 +24,10 @@ AC_ENABLE_SHARED AC_ENABLE_STATIC AC_PROG_CC AM_PROG_CC_C_O -CC_FLAG_VISIBILITY #[-fvisibility=hidden] + +CC_ATTRIBUTE_VISIBILITY([default], [ + CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"]) +]) CC_CHECK_CFLAGS_APPEND([-fno-strict-aliasing]) CC_CHECK_CFLAGS_APPEND([-g]) CC_CHECK_CFLAGS_APPEND([-std=gnu89]) @@ -43,7 +46,7 @@ AX_PTHREAD([ LIBS="$LIBS $PTHREAD_LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" ]) -AC_CHECK_LIB([dl], [dlopen]) +AC_SEARCH_LIBS([dlopen], [dl]) AC_SEARCH_LIBS([kstat_lookup], [kstat]) AC_SEARCH_LIBS([gethostbyname], [nsl]) AC_SEARCH_LIBS([perfstat_cpu], [perfstat]) diff --git a/deps/uv/docs/requirements.txt b/deps/uv/docs/requirements.txt new file mode 100644 index 00000000000000..8386e0178fabac --- /dev/null +++ b/deps/uv/docs/requirements.txt @@ -0,0 +1,42 @@ +# primary +Sphinx==3.5.4 + +# dependencies +alabaster==0.7.12 +appdirs==1.4.3 +Babel==2.9.0 +CacheControl==0.12.6 +certifi==2019.11.28 +chardet==3.0.4 +colorama==0.4.3 +contextlib2==0.6.0 +distlib==0.3.0 +distro==1.4.0 +docutils==0.16 +html5lib==1.0.1 +idna==2.8 +imagesize==1.2.0 +ipaddr==2.2.0 +Jinja2==2.11.3 +lockfile==0.12.2 +MarkupSafe==1.1.1 +msgpack==0.6.2 +packaging==20.3 +pep517==0.8.2 +progress==1.5 +Pygments==2.8.1 +pyparsing==2.4.6 +pytoml==0.1.21 +pytz==2021.1 +requests==2.22.0 +retrying==1.3.3 +six==1.14.0 +snowballstemmer==2.1.0 +sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.4 +urllib3==1.25.8 +webencodings==0.5.1 diff --git a/deps/uv/docs/src/errors.rst b/deps/uv/docs/src/errors.rst index c2daa8584eb9c3..c7240f3546f77e 100644 --- a/deps/uv/docs/src/errors.rst +++ b/deps/uv/docs/src/errors.rst @@ -251,6 +251,10 @@ Error constants operation not supported on socket +.. c:macro:: UV_EOVERFLOW + + value too large for defined data type + .. c:macro:: UV_EPERM operation not permitted @@ -331,6 +335,10 @@ Error constants illegal byte sequence +.. c:macro:: UV_ESOCKTNOSUPPORT + + socket type not supported + API --- diff --git a/deps/uv/docs/src/index.rst b/deps/uv/docs/src/index.rst index f696dc16279bf4..4b5d4d2c51195a 100644 --- a/deps/uv/docs/src/index.rst +++ b/deps/uv/docs/src/index.rst @@ -17,7 +17,7 @@ was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_, .. _Luvit: https://luvit.io .. _Julia: https://julialang.org .. _pyuv: https://github.com/saghul/pyuv -.. _others: https://github.com/libuv/libuv/wiki/Projects-that-use-libuv +.. _others: https://github.com/libuv/libuv/blob/v1.x/LINKS.md Features diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index b2725c399e431d..9a8595e577c3ea 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -533,7 +533,7 @@ API .. note:: This function currently only returns a non-zero value on Linux, based - on cgroups if it is present. + on cgroups if it is present, and on z/OS based on RLIMIT_MEMLIMIT. .. versionadded:: 1.29.0 diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst index 429ebdab28f5f1..0b42c4b3f8ca82 100644 --- a/deps/uv/docs/src/stream.rst +++ b/deps/uv/docs/src/stream.rst @@ -151,6 +151,11 @@ API This function is idempotent and may be safely called on a stopped stream. + This function will always succeed; hence, checking its return value is + unnecessary. A non-zero return indicates that finishing releasing resources + may be pending on the next input event on that TTY on Windows, and does not + indicate failure. + .. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb) Write data to stream. Buffers are written in order. Example: @@ -188,8 +193,9 @@ API initialized with `ipc` == 1. .. note:: - `send_handle` must be a TCP socket or pipe, which is a server or a connection (listening - or connected state). Bound sockets or pipes will be assumed to be servers. + `send_handle` must be a TCP, pipe and UDP handle on Unix, or a TCP + handle on Windows, which is a server or a connection (listening or + connected state). Bound sockets or pipes will be assumed to be servers. .. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs) @@ -202,6 +208,16 @@ API * < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent immediately). +.. c:function:: int uv_try_write2(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle) + + Same as :c:func:`uv_try_write` and extended write function for sending + handles over a pipe like c:func:`uv_write2`. + + Try to send a handle is not supported on Windows, + where it returns ``UV_EAGAIN``. + + .. versionadded:: 1.42.0 + .. c:function:: int uv_is_readable(const uv_stream_t* handle) Returns 1 if the stream is readable, 0 otherwise. diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst index 827fbaad6c0476..009767d55dc74e 100644 --- a/deps/uv/docs/src/udp.rst +++ b/deps/uv/docs/src/udp.rst @@ -53,6 +53,14 @@ Data types * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. */ UV_UDP_MMSG_FREE = 16, + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from supressing some ICMP error messages + * and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, /* * Indicates that recvmmsg should be used, if available. */ @@ -178,7 +186,8 @@ API with the address and port to bind to. :param flags: Indicate how the socket will be bound, - ``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported. + ``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, and ``UV_UDP_RECVERR`` + are supported. :returns: 0 on success, or an error code < 0 on failure. @@ -395,6 +404,11 @@ API :returns: 0 on success, or an error code < 0 on failure. + .. note:: + When using :man:`recvmmsg(2)`, the number of messages received at a time is limited + by the number of max size dgrams that will fit into the buffer allocated in `alloc_cb`, and + `suggested_size` in `alloc_cb` for udp_recv is always set to the size of 1 max size dgram. + .. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms). The use of this feature requires a buffer larger than 2 * 64KB to be passed to `alloc_cb`. diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 1e1fc94bfcc3dc..77503bde9f28e4 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -126,6 +126,7 @@ extern "C" { XX(ENOTEMPTY, "directory not empty") \ XX(ENOTSOCK, "socket operation on non-socket") \ XX(ENOTSUP, "operation not supported on socket") \ + XX(EOVERFLOW, "value too large for defined data type") \ XX(EPERM, "operation not permitted") \ XX(EPIPE, "broken pipe") \ XX(EPROTO, "protocol error") \ @@ -148,6 +149,7 @@ extern "C" { XX(ENOTTY, "inappropriate ioctl for device") \ XX(EFTYPE, "inappropriate file type or format") \ XX(EILSEQ, "illegal byte sequence") \ + XX(ESOCKTNOSUPPORT, "socket type not supported") \ #define UV_HANDLE_TYPE_MAP(XX) \ XX(ASYNC, async) \ @@ -526,6 +528,10 @@ UV_EXTERN int uv_write2(uv_write_t* req, UV_EXTERN int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs); +UV_EXTERN int uv_try_write2(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle); /* uv_write_t is a subclass of uv_req_t. */ struct uv_write_s { @@ -626,7 +632,14 @@ enum uv_udp_flags { * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. */ UV_UDP_MMSG_FREE = 16, - + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from suppressing some ICMP error + * messages and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, /* * Indicates that recvmmsg should be used, if available. */ diff --git a/deps/uv/include/uv/errno.h b/deps/uv/include/uv/errno.h index aadce9c14c9a6c..71906b3f5e65e6 100644 --- a/deps/uv/include/uv/errno.h +++ b/deps/uv/include/uv/errno.h @@ -445,4 +445,16 @@ # define UV__EILSEQ (-4027) #endif +#if defined(EOVERFLOW) && !defined(_WIN32) +# define UV__EOVERFLOW UV__ERR(EOVERFLOW) +#else +# define UV__EOVERFLOW (-4026) +#endif + +#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32) +# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT) +#else +# define UV__ESOCKTNOSUPPORT (-4025) +#endif + #endif /* UV_ERRNO_H_ */ diff --git a/deps/uv/include/uv/tree.h b/deps/uv/include/uv/tree.h index f936416e3d8313..2b28835fdedef2 100644 --- a/deps/uv/include/uv/tree.h +++ b/deps/uv/include/uv/tree.h @@ -251,7 +251,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ __left = __right = &__node; \ \ - while (1) { \ + for (;;) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index e94f1e02e15354..d5ba36c3ba9a1a 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 41 +#define UV_VERSION_MINOR 42 #define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/src/inet.c b/deps/uv/src/inet.c index 698ab232e53714..ddabf22fa52a0d 100644 --- a/deps/uv/src/inet.c +++ b/deps/uv/src/inet.c @@ -141,8 +141,9 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) { if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words)) *tp++ = ':'; *tp++ = '\0'; - if (UV_E2BIG == uv__strscpy(dst, tmp, size)) + if ((size_t) (tp - tmp) > size) return UV_ENOSPC; + uv__strscpy(dst, tmp, size); return 0; } diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 0998938f3e0d16..869ae95f58c7b8 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -161,7 +161,6 @@ static void post(QUEUE* q, enum uv__work_kind kind) { void uv__threadpool_cleanup(void) { -#ifndef _WIN32 unsigned int i; if (nthreads == 0) @@ -181,7 +180,6 @@ void uv__threadpool_cleanup(void) { threads = NULL; nthreads = 0; -#endif } diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h index 347d19365f7542..c48d058435a6b3 100644 --- a/deps/uv/src/unix/atomic-ops.h +++ b/deps/uv/src/unix/atomic-ops.h @@ -52,9 +52,11 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { UV_UNUSED(static void cpu_relax(void)) { #if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */ + __asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */ #elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) - __asm__ volatile("yield"); + __asm__ __volatile__ ("yield" ::: "memory"); +#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) + __asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory"); #endif } diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 63f268f795f100..71e9c525c4a77b 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -88,6 +88,10 @@ extern char** environ; # define uv__accept4 accept4 #endif +#if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__) +# include +#endif + static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ @@ -539,7 +543,13 @@ int uv__close_nocancel(int fd) { return close$NOCANCEL$UNIX2003(fd); #endif #pragma GCC diagnostic pop -#elif defined(__linux__) +#elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__) + long rc; + __sanitizer_syscall_pre_close(fd); + rc = syscall(SYS_close, fd); + __sanitizer_syscall_post_close(rc, fd); + return rc; +#elif defined(__linux__) && !defined(__SANITIZE_THREAD__) return syscall(SYS_close, fd); #else return close(fd); @@ -574,7 +584,7 @@ int uv__close(int fd) { return uv__close_nocheckstdio(fd); } - +#if UV__NONBLOCK_IS_IOCTL int uv__nonblock_ioctl(int fd, int set) { int r; @@ -589,7 +599,6 @@ int uv__nonblock_ioctl(int fd, int set) { } -#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__) int uv__cloexec_ioctl(int fd, int set) { int r; @@ -1174,7 +1183,9 @@ int uv__getpwuid_r(uv_passwd_t* pwd) { if (buf == NULL) return UV_ENOMEM; - r = getpwuid_r(uid, &pw, buf, bufsize, &result); + do + r = getpwuid_r(uid, &pw, buf, bufsize, &result); + while (r == EINTR); if (r != ERANGE) break; @@ -1184,7 +1195,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) { if (r != 0) { uv__free(buf); - return -r; + return UV__ERR(r); } if (result == NULL) { @@ -1570,7 +1581,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) { buf[*buflen] = '\0'; return 0; - } + } /* Case iii). Search PATH environment variable */ cloned_path = NULL; diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index d0ecd452d87c68..a7be0dd2f3ca14 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -33,9 +33,7 @@ #include #include /* sysconf */ -#if !TARGET_OS_IPHONE #include "darwin-stub.h" -#endif static uv_once_t once = UV_ONCE_INIT; static uint64_t (*time_func)(void); @@ -223,10 +221,10 @@ static int uv__get_cpu_speed(uint64_t* speed) { err = UV_ENOENT; core_foundation_handle = dlopen("/System/Library/Frameworks/" "CoreFoundation.framework/" - "Versions/A/CoreFoundation", + "CoreFoundation", RTLD_LAZY | RTLD_LOCAL); iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/" - "Versions/A/IOKit", + "IOKit", RTLD_LAZY | RTLD_LOCAL); if (core_foundation_handle == NULL || iokit_handle == NULL) @@ -304,6 +302,12 @@ static int uv__get_cpu_speed(uint64_t* speed) { pIOObjectRelease(it); err = 0; + + if (device_type_str != NULL) + pCFRelease(device_type_str); + if (clock_frequency_str != NULL) + pCFRelease(clock_frequency_str); + out: if (core_foundation_handle != NULL) dlclose(core_foundation_handle); diff --git a/deps/uv/src/unix/epoll.c b/deps/uv/src/unix/epoll.c new file mode 100644 index 00000000000000..97348e254b4556 --- /dev/null +++ b/deps/uv/src/unix/epoll.c @@ -0,0 +1,422 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" +#include +#include + +int uv__epoll_init(uv_loop_t* loop) { + int fd; + fd = epoll_create1(O_CLOEXEC); + + /* epoll_create1() can fail either because it's not implemented (old kernel) + * or because it doesn't understand the O_CLOEXEC flag. + */ + if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) { + fd = epoll_create(256); + + if (fd != -1) + uv__cloexec(fd, 1); + } + + loop->backend_fd = fd; + if (fd == -1) + return UV__ERR(errno); + + return 0; +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct epoll_event* events; + struct epoll_event dummy; + uintptr_t i; + uintptr_t nfds; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct epoll_event*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + if (events != NULL) + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if (events[i].data.fd == fd) + events[i].data.fd = -1; + + /* Remove the file descriptor from the epoll. + * This avoids a problem where the same file description remains open + * in another process, causing repeated junk epoll events. + * + * We pass in a dummy epoll_event, to work around a bug in old kernels. + */ + if (loop->backend_fd >= 0) { + /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that + * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings. + */ + memset(&dummy, 0, sizeof(dummy)); + epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy); + } +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct epoll_event e; + int rc; + + memset(&e, 0, sizeof(e)); + e.events = POLLIN; + e.data.fd = -1; + + rc = 0; + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e)) + if (errno != EEXIST) + rc = UV__ERR(errno); + + if (rc == 0) + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e)) + abort(); + + return rc; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes + * effectively infinite on 32 bits architectures. To avoid blocking + * indefinitely, we cap the timeout and poll again if necessary. + * + * Note that "30 minutes" is a simplification because it depends on + * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, + * that being the largest value I have seen in the wild (and only once.) + */ + static const int max_safe_timeout = 1789569; + static int no_epoll_pwait_cached; + static int no_epoll_wait_cached; + int no_epoll_pwait; + int no_epoll_wait; + struct epoll_event events[1024]; + struct epoll_event* pe; + struct epoll_event e; + int real_timeout; + QUEUE* q; + uv__io_t* w; + sigset_t sigset; + uint64_t sigmask; + uint64_t base; + int have_signals; + int nevents; + int count; + int nfds; + int fd; + int op; + int i; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + memset(&e, 0, sizeof(e)); + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + e.events = w->pevents; + e.data.fd = w->fd; + + if (w->events == 0) + op = EPOLL_CTL_ADD; + else + op = EPOLL_CTL_MOD; + + /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching + * events, skip the syscall and squelch the events after epoll_wait(). + */ + if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) { + if (errno != EEXIST) + abort(); + + assert(op == EPOLL_CTL_ADD); + + /* We've reactivated a file descriptor that's been watched before. */ + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e)) + abort(); + } + + w->events = w->pevents; + } + + sigmask = 0; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + sigemptyset(&sigset); + sigaddset(&sigset, SIGPROF); + sigmask |= 1 << (SIGPROF - 1); + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + real_timeout = timeout; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + user_timeout = 0; + } + + /* You could argue there is a dependency between these two but + * ultimately we don't care about their ordering with respect + * to one another. Worst case, we make a few system calls that + * could have been avoided because another thread already knows + * they fail with ENOSYS. Hardly the end of the world. + */ + no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached); + no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached); + + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + /* See the comment for max_safe_timeout for an explanation of why + * this is necessary. Executive summary: kernel bug workaround. + */ + if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) + timeout = max_safe_timeout; + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) + abort(); + + if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { + nfds = epoll_pwait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout, + &sigset); + if (nfds == -1 && errno == ENOSYS) { + uv__store_relaxed(&no_epoll_pwait_cached, 1); + no_epoll_pwait = 1; + } + } else { + nfds = epoll_wait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + if (nfds == -1 && errno == ENOSYS) { + uv__store_relaxed(&no_epoll_wait_cached, 1); + no_epoll_wait = 1; + } + } + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* We may have been inside the system call for longer than |timeout| + * milliseconds so we need to update the timestamp to avoid drift. + */ + goto update_timeout; + } + + if (nfds == -1) { + if (errno == ENOSYS) { + /* epoll_wait() or epoll_pwait() failed, try the other system call. */ + assert(no_epoll_wait == 0 || no_epoll_pwait == 0); + continue; + } + + if (errno != EINTR) + abort(); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + have_signals = 0; + nevents = 0; + + { + /* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */ + union { + struct epoll_event* events; + uv__io_t* watchers; + } x; + + x.events = events; + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = x.watchers; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + } + + for (i = 0; i < nfds; i++) { + pe = events + i; + fd = pe->data.fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, disarm it. + * + * Ignore all errors because we may be racing with another thread + * when the file descriptor is closed. + */ + epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe); + continue; + } + + /* Give users only events they're interested in. Prevents spurious + * callbacks when previous callback invocation in this loop has stopped + * the current watcher. Also, filters out events that users has not + * requested us to watch. + */ + pe->events &= w->pevents | POLLERR | POLLHUP; + + /* Work around an epoll quirk where it sometimes reports just the + * EPOLLERR or EPOLLHUP event. In order to force the event loop to + * move forward, we merge in the read/write events that the watcher + * is interested in; uv__read() and uv__write() will then deal with + * the error or hangup in the usual fashion. + * + * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user + * reads the available data, calls uv_read_stop(), then sometime later + * calls uv_read_start() again. By then, libuv has forgotten about the + * hangup and the kernel won't report EPOLLIN again because there's + * nothing left to read. If anything, libuv is to blame here. The + * current hack is just a quick bandaid; to properly fix it, libuv + * needs to remember the error/hangup event. We should get that for + * free when we switch over to edge-triggered I/O. + */ + if (pe->events == POLLERR || pe->events == POLLHUP) + pe->events |= + w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); + + if (pe->events != 0) { + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->events); + } + + nevents++; + } + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + real_timeout -= (loop->time - base); + if (real_timeout <= 0) + return; + + timeout = real_timeout; + } +} + diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index fe795a0e75ea1a..170b897e2023d2 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -265,8 +265,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { -#if __FreeBSD__ >= 11 - return sendmmsg(fd, mmsg, vlen, /* flags */ 0); +#if __FreeBSD__ >= 11 && !defined(__DragonFly__) + return sendmmsg(fd, + (struct mmsghdr*) mmsg, + vlen, + 0 /* flags */); #else return errno = ENOSYS, -1; #endif @@ -274,8 +277,12 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { -#if __FreeBSD__ >= 11 - return recvmmsg(fd, mmsg, vlen, 0 /* flags */, NULL /* timeout */); +#if __FreeBSD__ >= 11 && !defined(__DragonFly__) + return recvmmsg(fd, + (struct mmsghdr*) mmsg, + vlen, + 0 /* flags */, + NULL /* timeout */); #else return errno = ENOSYS, -1; #endif diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index fd7ae08755f519..eb17fb4a23eb82 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -56,6 +56,10 @@ # define HAVE_PREADV 0 #endif +#if defined(__linux__) +# include "sys/utsname.h" +#endif + #if defined(__linux__) || defined(__sun) # include # include @@ -901,6 +905,50 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) { } +#ifdef __linux__ +static unsigned uv__kernel_version(void) { + static unsigned cached_version; + struct utsname u; + unsigned version; + unsigned major; + unsigned minor; + unsigned patch; + + version = uv__load_relaxed(&cached_version); + if (version != 0) + return version; + + if (-1 == uname(&u)) + return 0; + + if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch)) + return 0; + + version = major * 65536 + minor * 256 + patch; + uv__store_relaxed(&cached_version, version); + + return version; +} + + +/* Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from command + * in copy_file_range() when it shouldn't. There is no workaround except to + * fall back to a regular copy. + */ +static int uv__is_buggy_cephfs(int fd) { + struct statfs s; + + if (-1 == fstatfs(fd, &s)) + return 0; + + if (s.f_type != /* CephFS */ 0xC36400) + return 0; + + return uv__kernel_version() < /* 4.20.0 */ 0x041400; +} +#endif /* __linux__ */ + + static ssize_t uv__fs_sendfile(uv_fs_t* req) { int in_fd; int out_fd; @@ -917,15 +965,20 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) { #ifdef __linux__ { - static int copy_file_range_support = 1; + static int no_copy_file_range_support; - if (copy_file_range_support) { + if (uv__load_relaxed(&no_copy_file_range_support) == 0) { r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0); if (r == -1 && errno == ENOSYS) { /* ENOSYS - it will never work */ errno = 0; - copy_file_range_support = 0; + uv__store_relaxed(&no_copy_file_range_support, 1); + } else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) { + /* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS + copy-from command when it shouldn't */ + errno = 0; + uv__store_relaxed(&no_copy_file_range_support, 1); } else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) { /* ENOTSUP - it could work on another file system type */ /* EXDEV - it will not work when in_fd and out_fd are not on the same @@ -1357,7 +1410,8 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) { dst->st_birthtim.tv_nsec = src->st_ctimensec; dst->st_flags = 0; dst->st_gen = 0; -#elif !defined(_AIX) && ( \ +#elif !defined(_AIX) && \ + !defined(__MVS__) && ( \ defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__OpenBSD__) || \ diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index a51f29b3f6db55..bf4f1f6a5180ab 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -595,8 +595,7 @@ static int uv__fsevents_global_init(void) { static int uv__fsevents_loop_init(uv_loop_t* loop) { CFRunLoopSourceContext ctx; uv__cf_loop_state_t* state; - pthread_attr_t attr_storage; - pthread_attr_t* attr; + pthread_attr_t attr; int err; if (loop->cf_state != NULL) @@ -641,25 +640,19 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) { goto fail_signal_source_create; } - /* In the unlikely event that pthread_attr_init() fails, create the thread - * with the default stack size. We'll use a little more address space but - * that in itself is not a fatal error. - */ - attr = &attr_storage; - if (pthread_attr_init(attr)) - attr = NULL; + if (pthread_attr_init(&attr)) + abort(); - if (attr != NULL) - if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN)) - abort(); + if (pthread_attr_setstacksize(&attr, uv__thread_stack_size())) + abort(); loop->cf_state = state; /* uv_thread_t is an alias for pthread_t. */ - err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop)); + err = UV__ERR(pthread_create(&loop->cf_thread, &attr, uv__cf_loop_runner, loop)); - if (attr != NULL) - pthread_attr_destroy(attr); + if (pthread_attr_destroy(&attr)) + abort(); if (err) goto fail_thread_create; diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c index d7ca7d1a446838..77337ace9454e0 100644 --- a/deps/uv/src/unix/getaddrinfo.c +++ b/deps/uv/src/unix/getaddrinfo.c @@ -21,9 +21,6 @@ /* Expose glibc-specific EAI_* error codes. Needs to be defined before we * include any headers. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif #include "uv.h" #include "internal.h" diff --git a/deps/uv/src/unix/ibmi.c b/deps/uv/src/unix/ibmi.c index 96efc02bad6071..8c6ae636329e5b 100644 --- a/deps/uv/src/unix/ibmi.c +++ b/deps/uv/src/unix/ibmi.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -166,7 +165,7 @@ static void iconv_a2e(const char* src, unsigned char dst[], size_t length) { srclen = strlen(src); if (srclen > length) - abort(); + srclen = length; for (i = 0; i < srclen; i++) dst[i] = a2e[src[i]]; /* padding the remaining part with spaces */ @@ -360,6 +359,10 @@ static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) { if (rc != 0) return rc; + if (err.bytes_available > 0) { + return -1; + } + /* convert ebcdic loca_adapter_address to ascii first */ iconv_e2a(rcvr.loca_adapter_address, mac_addr, sizeof(rcvr.loca_adapter_address)); @@ -443,9 +446,42 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0; if (!address->is_internal) { - int rc = get_ibmi_physical_address(address->name, &address->phys_addr); - if (rc != 0) - r = rc; + int rc = -1; + size_t name_len = strlen(address->name); + /* To get the associated MAC address, we must convert the address to a + * line description. Normally, the name field contains the line + * description name, but for VLANs it has the VLAN appended with a + * period. Since object names can also contain periods and numbers, there + * is no way to know if a returned name is for a VLAN or not. eg. + * *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1 + * + * Instead, we apply the same heuristic used by some of the XPF ioctls: + * - names > 10 *must* contain a VLAN + * - assume names <= 10 do not contain a VLAN and try directly + * - if >10 or QDCRLIND returned an error, try to strip off a VLAN + * and try again + * - if we still get an error or couldn't find a period, leave the MAC as + * 00:00:00:00:00:00 + */ + if (name_len <= 10) { + /* Assume name does not contain a VLAN ID */ + rc = get_ibmi_physical_address(address->name, &address->phys_addr); + } + + if (name_len > 10 || rc != 0) { + /* The interface name must contain a VLAN ID suffix. Attempt to strip + * it off so we can get the line description to pass to QDCRLIND. + */ + char* temp_name = uv__strdup(address->name); + char* dot = strrchr(temp_name, '.'); + if (dot != NULL) { + *dot = '\0'; + if (strlen(temp_name) <= 10) { + rc = get_ibmi_physical_address(temp_name, &address->phys_addr); + } + } + uv__free(temp_name); + } } address++; @@ -498,4 +534,4 @@ int uv_get_process_title(char* buffer, size_t size) { } void uv__process_title_cleanup(void) { -} \ No newline at end of file +} diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 3bdf7283bd4fd8..12d4da93686e99 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -62,6 +62,17 @@ # include #endif +/* + * Define common detection for active Thread Sanitizer + * - clang uses __has_feature(thread_sanitizer) + * - gcc-7+ uses __SANITIZE_THREAD__ + */ +#if defined(__has_feature) +# if __has_feature(thread_sanitizer) +# define __SANITIZE_THREAD__ 1 +# endif +#endif + #if defined(PATH_MAX) # define UV__PATH_MAX PATH_MAX #else @@ -165,9 +176,11 @@ struct uv__stream_queued_fds_s { defined(__NetBSD__) #define uv__cloexec uv__cloexec_ioctl #define uv__nonblock uv__nonblock_ioctl +#define UV__NONBLOCK_IS_IOCTL 1 #else #define uv__cloexec uv__cloexec_fcntl #define uv__nonblock uv__nonblock_fcntl +#define UV__NONBLOCK_IS_IOCTL 0 #endif /* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute @@ -246,6 +259,7 @@ int uv__signal_loop_fork(uv_loop_t* loop); /* platform specific */ uint64_t uv__hrtime(uv_clocktype_t type); int uv__kqueue_init(uv_loop_t* loop); +int uv__epoll_init(uv_loop_t* loop); int uv__platform_loop_init(uv_loop_t* loop); void uv__platform_loop_delete(uv_loop_t* loop); void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); @@ -261,6 +275,7 @@ void uv__prepare_close(uv_prepare_t* handle); void uv__process_close(uv_process_t* handle); void uv__stream_close(uv_stream_t* handle); void uv__tcp_close(uv_tcp_t* handle); +size_t uv__thread_stack_size(void); void uv__udp_close(uv_udp_t* handle); void uv__udp_finish_close(uv_udp_t* handle); uv_handle_type uv__handle_type(int fd); @@ -321,7 +336,8 @@ int uv__getsockpeername(const uv_handle_t* handle, #if defined(__linux__) || \ defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) + defined(__FreeBSD_kernel__) || \ + defined(__DragonFly__) #define HAVE_MMSG 1 struct uv__mmsghdr { struct msghdr msg_hdr; @@ -334,5 +350,11 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen); #define HAVE_MMSG 0 #endif +#if defined(__sun) +#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L +size_t strnlen(const char* s, size_t maxlen); +#endif +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index c356e96d2dec5b..2716e2be65dfe4 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -82,29 +82,12 @@ static int read_times(FILE* statfile_fp, static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci); static uint64_t read_cpufreq(unsigned int cpunum); - int uv__platform_loop_init(uv_loop_t* loop) { - int fd; - fd = epoll_create1(O_CLOEXEC); - - /* epoll_create1() can fail either because it's not implemented (old kernel) - * or because it doesn't understand the O_CLOEXEC flag. - */ - if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) { - fd = epoll_create(256); - - if (fd != -1) - uv__cloexec(fd, 1); - } - - loop->backend_fd = fd; + loop->inotify_fd = -1; loop->inotify_watchers = NULL; - if (fd == -1) - return UV__ERR(errno); - - return 0; + return uv__epoll_init(loop); } @@ -134,380 +117,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct epoll_event* events; - struct epoll_event dummy; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - assert(fd >= 0); - - events = (struct epoll_event*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events != NULL) - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if (events[i].data.fd == fd) - events[i].data.fd = -1; - - /* Remove the file descriptor from the epoll. - * This avoids a problem where the same file description remains open - * in another process, causing repeated junk epoll events. - * - * We pass in a dummy epoll_event, to work around a bug in old kernels. - */ - if (loop->backend_fd >= 0) { - /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that - * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings. - */ - memset(&dummy, 0, sizeof(dummy)); - epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy); - } -} - - -int uv__io_check_fd(uv_loop_t* loop, int fd) { - struct epoll_event e; - int rc; - - memset(&e, 0, sizeof(e)); - e.events = POLLIN; - e.data.fd = -1; - - rc = 0; - if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e)) - if (errno != EEXIST) - rc = UV__ERR(errno); - - if (rc == 0) - if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e)) - abort(); - - return rc; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes - * effectively infinite on 32 bits architectures. To avoid blocking - * indefinitely, we cap the timeout and poll again if necessary. - * - * Note that "30 minutes" is a simplification because it depends on - * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, - * that being the largest value I have seen in the wild (and only once.) - */ - static const int max_safe_timeout = 1789569; - static int no_epoll_pwait_cached; - static int no_epoll_wait_cached; - int no_epoll_pwait; - int no_epoll_wait; - struct epoll_event events[1024]; - struct epoll_event* pe; - struct epoll_event e; - int real_timeout; - QUEUE* q; - uv__io_t* w; - sigset_t sigset; - uint64_t sigmask; - uint64_t base; - int have_signals; - int nevents; - int count; - int nfds; - int fd; - int op; - int i; - int user_timeout; - int reset_timeout; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - memset(&e, 0, sizeof(e)); - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - e.events = w->pevents; - e.data.fd = w->fd; - - if (w->events == 0) - op = EPOLL_CTL_ADD; - else - op = EPOLL_CTL_MOD; - - /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching - * events, skip the syscall and squelch the events after epoll_wait(). - */ - if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) { - if (errno != EEXIST) - abort(); - - assert(op == EPOLL_CTL_ADD); - - /* We've reactivated a file descriptor that's been watched before. */ - if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e)) - abort(); - } - - w->events = w->pevents; - } - - sigmask = 0; - if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { - sigemptyset(&sigset); - sigaddset(&sigset, SIGPROF); - sigmask |= 1 << (SIGPROF - 1); - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - real_timeout = timeout; - - if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { - reset_timeout = 1; - user_timeout = timeout; - timeout = 0; - } else { - reset_timeout = 0; - user_timeout = 0; - } - - /* You could argue there is a dependency between these two but - * ultimately we don't care about their ordering with respect - * to one another. Worst case, we make a few system calls that - * could have been avoided because another thread already knows - * they fail with ENOSYS. Hardly the end of the world. - */ - no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached); - no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached); - - for (;;) { - /* Only need to set the provider_entry_time if timeout != 0. The function - * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. - */ - if (timeout != 0) - uv__metrics_set_provider_entry_time(loop); - - /* See the comment for max_safe_timeout for an explanation of why - * this is necessary. Executive summary: kernel bug workaround. - */ - if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) - timeout = max_safe_timeout; - - if (sigmask != 0 && no_epoll_pwait != 0) - if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) - abort(); - - if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { - nfds = epoll_pwait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout, - &sigset); - if (nfds == -1 && errno == ENOSYS) { - uv__store_relaxed(&no_epoll_pwait_cached, 1); - no_epoll_pwait = 1; - } - } else { - nfds = epoll_wait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout); - if (nfds == -1 && errno == ENOSYS) { - uv__store_relaxed(&no_epoll_wait_cached, 1); - no_epoll_wait = 1; - } - } - - if (sigmask != 0 && no_epoll_pwait != 0) - if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) - abort(); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - - if (reset_timeout != 0) { - timeout = user_timeout; - reset_timeout = 0; - } - - if (timeout == -1) - continue; - - if (timeout == 0) - return; - - /* We may have been inside the system call for longer than |timeout| - * milliseconds so we need to update the timestamp to avoid drift. - */ - goto update_timeout; - } - - if (nfds == -1) { - if (errno == ENOSYS) { - /* epoll_wait() or epoll_pwait() failed, try the other system call. */ - assert(no_epoll_wait == 0 || no_epoll_pwait == 0); - continue; - } - - if (errno != EINTR) - abort(); - - if (reset_timeout != 0) { - timeout = user_timeout; - reset_timeout = 0; - } - - if (timeout == -1) - continue; - - if (timeout == 0) - return; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - have_signals = 0; - nevents = 0; - - { - /* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */ - union { - struct epoll_event* events; - uv__io_t* watchers; - } x; - - x.events = events; - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = x.watchers; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - } - - for (i = 0; i < nfds; i++) { - pe = events + i; - fd = pe->data.fd; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - - assert(fd >= 0); - assert((unsigned) fd < loop->nwatchers); - - w = loop->watchers[fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. - * - * Ignore all errors because we may be racing with another thread - * when the file descriptor is closed. - */ - epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe); - continue; - } - - /* Give users only events they're interested in. Prevents spurious - * callbacks when previous callback invocation in this loop has stopped - * the current watcher. Also, filters out events that users has not - * requested us to watch. - */ - pe->events &= w->pevents | POLLERR | POLLHUP; - - /* Work around an epoll quirk where it sometimes reports just the - * EPOLLERR or EPOLLHUP event. In order to force the event loop to - * move forward, we merge in the read/write events that the watcher - * is interested in; uv__read() and uv__write() will then deal with - * the error or hangup in the usual fashion. - * - * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user - * reads the available data, calls uv_read_stop(), then sometime later - * calls uv_read_start() again. By then, libuv has forgotten about the - * hangup and the kernel won't report EPOLLIN again because there's - * nothing left to read. If anything, libuv is to blame here. The - * current hack is just a quick bandaid; to properly fix it, libuv - * needs to remember the error/hangup event. We should get that for - * free when we switch over to edge-triggered I/O. - */ - if (pe->events == POLLERR || pe->events == POLLHUP) - pe->events |= - w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); - - if (pe->events != 0) { - /* Run signal watchers last. This also affects child process watchers - * because those are implemented in terms of signal watchers. - */ - if (w == &loop->signal_io_watcher) { - have_signals = 1; - } else { - uv__metrics_update_idle_time(loop); - w->cb(loop, w, pe->events); - } - - nevents++; - } - } - - if (reset_timeout != 0) { - timeout = user_timeout; - reset_timeout = 0; - } - - if (have_signals != 0) { - uv__metrics_update_idle_time(loop); - loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); - } - - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (have_signals != 0) - return; /* Event loop should cycle now so don't poll again. */ - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - real_timeout -= (loop->time - base); - if (real_timeout <= 0) - return; - - timeout = real_timeout; - } -} - uint64_t uv__hrtime(uv_clocktype_t type) { static clock_t fast_clock_id = -1; @@ -740,14 +349,19 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) { } -/* Also reads the CPU frequency on x86. The other architectures only have - * a BogoMIPS field, which may not be very accurate. +/* Also reads the CPU frequency on ppc and x86. The other architectures only + * have a BogoMIPS field, which may not be very accurate. * * Note: Simply returns on error, uv_cpu_info() takes care of the cleanup. */ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { +#if defined(__PPC__) + static const char model_marker[] = "cpu\t\t: "; + static const char speed_marker[] = "clock\t\t: "; +#else static const char model_marker[] = "model name\t: "; static const char speed_marker[] = "cpu MHz\t\t: "; +#endif const char* inferred_model; unsigned int model_idx; unsigned int speed_idx; @@ -769,6 +383,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { #if defined(__arm__) || \ defined(__i386__) || \ defined(__mips__) || \ + defined(__PPC__) || \ defined(__x86_64__) fp = uv__open_file("/proc/cpuinfo"); if (fp == NULL) @@ -817,7 +432,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { } fclose(fp); -#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */ +#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */ /* Now we want to make sure that all the models contain *something* because * it's not safe to leave them as null. Copy the last entry unless there @@ -855,9 +470,9 @@ static int read_times(FILE* statfile_fp, char buf[1024]; ticks = (unsigned int)sysconf(_SC_CLK_TCK); - multiplier = ((uint64_t)1000L / ticks); assert(ticks != (unsigned int) -1); assert(ticks != 0); + multiplier = ((uint64_t)1000L / ticks); rewind(statfile_fp); diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c index 42b601adbf898a..c1bd260e16e5e9 100644 --- a/deps/uv/src/unix/linux-inotify.c +++ b/deps/uv/src/unix/linux-inotify.c @@ -178,7 +178,7 @@ static void uv__inotify_read(uv_loop_t* loop, /* needs to be large enough for sizeof(inotify_event) + strlen(path) */ char buf[4096]; - while (1) { + for (;;) { do size = read(loop->inotify_fd, buf, sizeof(buf)); while (size == -1 && errno == EINTR); diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h index c85231f6bf4436..b4d9082d46f99b 100644 --- a/deps/uv/src/unix/linux-syscalls.h +++ b/deps/uv/src/unix/linux-syscalls.h @@ -22,9 +22,6 @@ #ifndef UV_LINUX_SYSCALL_H_ #define UV_LINUX_SYSCALL_H_ -#undef _GNU_SOURCE -#define _GNU_SOURCE - #include #include #include diff --git a/deps/uv/src/unix/os390-proctitle.c b/deps/uv/src/unix/os390-proctitle.c new file mode 100644 index 00000000000000..ccda97c9ac5822 --- /dev/null +++ b/deps/uv/src/unix/os390-proctitle.c @@ -0,0 +1,136 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static char* process_title = NULL; +static void* args_mem = NULL; + + +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + +char** uv_setup_args(int argc, char** argv) { + char** new_argv; + size_t size; + char* s; + int i; + + if (argc <= 0) + return argv; + + /* Calculate how much memory we need for the argv strings. */ + size = 0; + for (i = 0; i < argc; i++) + size += strlen(argv[i]) + 1; + + /* Add space for the argv pointers. */ + size += (argc + 1) * sizeof(char*); + + new_argv = uv__malloc(size); + if (new_argv == NULL) + return argv; + + /* Copy over the strings and set up the pointer table. */ + s = (char*) &new_argv[argc + 1]; + for (i = 0; i < argc; i++) { + size = strlen(argv[i]) + 1; + memcpy(s, argv[i], size); + new_argv[i] = s; + s += size; + } + new_argv[i] = NULL; + + args_mem = new_argv; + process_title = uv__strdup(argv[0]); + + return new_argv; +} + + +int uv_set_process_title(const char* title) { + char* new_title; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL) + return UV_ENOBUFS; + + /* We cannot free this pointer when libuv shuts down, + * the process may still be using it. + */ + new_title = uv__strdup(title); + if (new_title == NULL) + return UV_ENOMEM; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title != NULL) + uv__free(process_title); + + process_title = new_title; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + + if (buffer == NULL || size == 0) + return UV_EINVAL; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL || process_title == NULL) + return UV_ENOBUFS; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + len = strlen(process_title); + + if (size <= len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + strcpy(buffer, process_title); + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +void uv__process_title_cleanup(void) { + uv__free(args_mem); /* Keep valgrind happy. */ + args_mem = NULL; +} diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 491e950c503d40..c19155339c3124 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -27,12 +27,6 @@ #include #include -#define CW_INTRPT 1 -#define CW_CONDVAR 32 - -#pragma linkage(BPX4CTW, OS) -#pragma linkage(BPX1CTW, OS) - static QUEUE global_epoll_queue; static uv_mutex_t global_epoll_lock; static uv_once_t once = UV_ONCE_INIT; @@ -55,7 +49,7 @@ int scandir(const char* maindir, struct dirent*** namelist, if (!mdir) return -1; - while (1) { + for (;;) { dirent = readdir(mdir); if (!dirent) break; @@ -381,46 +375,6 @@ void epoll_queue_close(uv__os390_epoll* lst) { } -int nanosleep(const struct timespec* req, struct timespec* rem) { - unsigned nano; - unsigned seconds; - unsigned events; - unsigned secrem; - unsigned nanorem; - int rv; - int err; - int rsn; - - nano = (int)req->tv_nsec; - seconds = req->tv_sec; - events = CW_CONDVAR | CW_INTRPT; - secrem = 0; - nanorem = 0; - -#if defined(_LP64) - BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn); -#else - BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn); -#endif - - /* Don't clobber errno unless BPX1CTW/BPX4CTW errored. - * Don't leak EAGAIN, that just means the timeout expired. - */ - if (rv == -1) - if (err == EAGAIN) - rv = 0; - else - errno = err; - - if (rem != NULL && (rv == 0 || err == EINTR)) { - rem->tv_nsec = nanorem; - rem->tv_sec = secrem; - } - - return rv; -} - - char* mkdtemp(char* path) { static const char* tempchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -550,15 +504,6 @@ ssize_t os390_readlink(const char* path, char* buf, size_t len) { } -size_t strnlen(const char* str, size_t maxlen) { - char* p = memchr(str, 0, maxlen); - if (p == NULL) - return maxlen; - else - return p - str; -} - - int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value) { UNREACHABLE(); } diff --git a/deps/uv/src/unix/os390-syscalls.h b/deps/uv/src/unix/os390-syscalls.h index 86416bbc551e19..7d59b75e470945 100644 --- a/deps/uv/src/unix/os390-syscalls.h +++ b/deps/uv/src/unix/os390-syscalls.h @@ -28,6 +28,7 @@ #include #include #include +#include "zos-base.h" #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_DEL 2 @@ -57,7 +58,6 @@ int epoll_wait(uv__os390_epoll* ep, struct epoll_event *events, int maxevents, i int epoll_file_close(int fd); /* utility functions */ -int nanosleep(const struct timespec* req, struct timespec* rem); int scandir(const char* maindir, struct dirent*** namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index 3bb44266d93cc1..bf0448b519080e 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include "zos-base.h" #if defined(__clang__) #include "csrsic.h" #else @@ -61,12 +63,6 @@ /* Address of the rsm control and enumeration area. */ #define CVTRCEP_OFFSET 0x490 -/* - Number of frames currently available to system. - Excluded are frames backing perm storage, frames offline, and bad frames. -*/ -#define RCEPOOL_OFFSET 0x004 - /* Total number of frames currently on all available frame queues. */ #define RCEAFC_OFFSET 0x088 @@ -144,102 +140,8 @@ uint64_t uv__hrtime(uv_clocktype_t type) { } -/* - Get the exe path using the thread entry information - in the address space. -*/ -static int getexe(const int pid, char* buf, size_t len) { - struct { - int pid; - int thid[2]; - char accesspid; - char accessthid; - char asid[2]; - char loginname[8]; - char flag; - char len; - } Input_data; - - union { - struct { - char gthb[4]; - int pid; - int thid[2]; - char accesspid; - char accessthid[3]; - int lenused; - int offsetProcess; - int offsetConTTY; - int offsetPath; - int offsetCommand; - int offsetFileData; - int offsetThread; - } Output_data; - char buf[2048]; - } Output_buf; - - struct Output_path_type { - char gthe[4]; - short int len; - char path[1024]; - }; - - int Input_length; - int Output_length; - void* Input_address; - void* Output_address; - struct Output_path_type* Output_path; - int rv; - int rc; - int rsn; - - Input_length = PGTH_LEN; - Output_length = sizeof(Output_buf); - Output_address = &Output_buf; - Input_address = &Input_data; - memset(&Input_data, 0, sizeof Input_data); - Input_data.flag |= PGTHAPATH; - Input_data.pid = pid; - Input_data.accesspid = PGTH_CURRENT; - -#ifdef _LP64 - BPX4GTH(&Input_length, - &Input_address, - &Output_length, - &Output_address, - &rv, - &rc, - &rsn); -#else - BPX1GTH(&Input_length, - &Input_address, - &Output_length, - &Output_address, - &rv, - &rc, - &rsn); -#endif - - if (rv == -1) { - errno = rc; - return -1; - } - - /* Check highest byte to ensure data availability */ - assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A'); - - /* Get the offset from the lowest 3 bytes */ - Output_path = (struct Output_path_type*) ((char*) (&Output_buf) + - (Output_buf.Output_data.offsetPath & 0x00FFFFFF)); - - if (Output_path->len >= len) { - errno = ENOBUFS; - return -1; - } - - uv__strscpy(buf, Output_path->path, len); - - return 0; +static int getexe(char* buf, size_t len) { + return uv__strscpy(buf, __getargv()[0], len); } @@ -259,8 +161,7 @@ int uv_exepath(char* buffer, size_t* size) { if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; - pid = getpid(); - res = getexe(pid, args, sizeof(args)); + res = getexe(args, sizeof(args)); if (res < 0) return UV_EINVAL; @@ -275,25 +176,25 @@ uint64_t uv_get_free_memory(void) { data_area_ptr rcep = {0}; cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET); - freeram = *((uint64_t*)(rcep.deref + RCEAFC_OFFSET)) * 4; + freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096; return freeram; } uint64_t uv_get_total_memory(void) { - uint64_t totalram; - - data_area_ptr cvt = {0}; - data_area_ptr rcep = {0}; - cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); - rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET); - totalram = *((uint64_t*)(rcep.deref + RCEPOOL_OFFSET)) * 4; - return totalram; + /* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */ + return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024; } uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + struct rlimit rl; + + /* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */ + if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0) + return rl.rlim_cur * 1024 * 1024; + + return 0; /* There is no memory limit set. */ } @@ -733,6 +634,10 @@ static int os390_message_queue_handler(uv__os390_epoll* ep) { /* Some event that we are not interested in. */ return 0; + /* `__rfim_utok` is treated as text when it should be treated as binary while + * running in ASCII mode, resulting in an unwanted autoconversion. + */ + __a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok)); handle = *(uv_fs_event_t**)(msg.__rfim_utok); handle->cb(handle, uv__basename_r(handle->path), events, 0); return 1; @@ -959,9 +864,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } } -void uv__set_process_title(const char* title) { - /* do nothing */ -} int uv__io_fork(uv_loop_t* loop) { /* diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c index 7a1bc7b9dd58d8..7a12e2d1488a9d 100644 --- a/deps/uv/src/unix/poll.c +++ b/deps/uv/src/unix/poll.c @@ -79,9 +79,10 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { * Workaround for e.g. kqueue fds not supporting ioctls. */ err = uv__nonblock(fd, 1); +#if UV__NONBLOCK_IS_IOCTL if (err == UV_ENOTTY) - if (uv__nonblock == uv__nonblock_ioctl) - err = uv__nonblock_fcntl(fd, 1); + err = uv__nonblock_fcntl(fd, 1); +#endif if (err) return err; diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 8f94c53b249978..f4aebb0490e198 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -44,6 +44,10 @@ extern char **environ; # include #endif +#if defined(__MVS__) +# include "zos-base.h" +#endif + static void uv__chld(uv_signal_t* handle, int signum) { uv_process_t* process; @@ -197,6 +201,12 @@ static void uv__write_int(int fd, int val) { } +static void uv__write_errno(int error_fd) { + uv__write_int(error_fd, UV__ERR(errno)); + _exit(127); +} + + #if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) /* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be * avoided. Since this isn't called on those targets, the function @@ -225,10 +235,8 @@ static void uv__process_child_init(const uv_process_options_t* options, if (use_fd < 0 || use_fd >= fd) continue; pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count); - if (pipes[fd][1] == -1) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if (pipes[fd][1] == -1) + uv__write_errno(error_fd); } for (fd = 0; fd < stdio_count; fd++) { @@ -245,10 +253,8 @@ static void uv__process_child_init(const uv_process_options_t* options, use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR); close_fd = use_fd; - if (use_fd < 0) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if (use_fd < 0) + uv__write_errno(error_fd); } } @@ -257,10 +263,8 @@ static void uv__process_child_init(const uv_process_options_t* options, else fd = dup2(use_fd, fd); - if (fd == -1) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if (fd == -1) + uv__write_errno(error_fd); if (fd <= 2) uv__nonblock_fcntl(fd, 0); @@ -276,10 +280,8 @@ static void uv__process_child_init(const uv_process_options_t* options, uv__close(use_fd); } - if (options->cwd != NULL && chdir(options->cwd)) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if (options->cwd != NULL && chdir(options->cwd)) + uv__write_errno(error_fd); if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) { /* When dropping privileges from root, the `setgroups` call will @@ -292,15 +294,11 @@ static void uv__process_child_init(const uv_process_options_t* options, SAVE_ERRNO(setgroups(0, NULL)); } - if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) + uv__write_errno(error_fd); - if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) { - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); - } + if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) + uv__write_errno(error_fd); if (options->env != NULL) { environ = options->env; @@ -323,22 +321,23 @@ static void uv__process_child_init(const uv_process_options_t* options, if (SIG_ERR != signal(n, SIG_DFL)) continue; - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); + uv__write_errno(error_fd); } /* Reset signal mask. */ sigemptyset(&set); err = pthread_sigmask(SIG_SETMASK, &set, NULL); - if (err != 0) { - uv__write_int(error_fd, UV__ERR(err)); - _exit(127); - } + if (err != 0) + uv__write_errno(error_fd); +#ifdef __MVS__ + execvpe(options->file, options->args, environ); +#else execvp(options->file, options->args); - uv__write_int(error_fd, UV__ERR(errno)); - _exit(127); +#endif + + uv__write_errno(error_fd); } #endif diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 9e39545e44a0ff..9d1f00ddf66e29 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -84,10 +84,7 @@ char** uv_setup_args(int argc, char** argv) { } new_argv[i] = NULL; - /* argv is not adjacent on z/os, we use just argv[0] on that platform. */ -#ifndef __MVS__ pt.cap = argv[i - 1] + size - argv[0]; -#endif args_mem = new_argv; process_title = pt; diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 106785e4574ea0..bc64fe8f44b26d 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -164,7 +164,7 @@ static void uv__stream_osx_select(void* arg) { else max_fd = s->int_fd; - while (1) { + for (;;) { /* Terminate on semaphore */ if (uv_sem_trywait(&s->close_sem) == 0) break; @@ -195,7 +195,7 @@ static void uv__stream_osx_select(void* arg) { /* Empty socketpair's buffer in case of interruption */ if (FD_ISSET(s->int_fd, s->sread)) - while (1) { + for (;;) { r = read(s->int_fd, buf, sizeof(buf)); if (r == sizeof(buf)) @@ -799,33 +799,21 @@ static int uv__handle_fd(uv_handle_t* handle) { } } -static void uv__write(uv_stream_t* stream) { +static int uv__try_write(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { struct iovec* iov; - QUEUE* q; - uv_write_t* req; int iovmax; int iovcnt; ssize_t n; - int err; - -start: - - assert(uv__stream_fd(stream) >= 0); - - if (QUEUE_EMPTY(&stream->write_queue)) - return; - - q = QUEUE_HEAD(&stream->write_queue); - req = QUEUE_DATA(q, uv_write_t, queue); - assert(req->handle == stream); /* * Cast to iovec. We had to have our own uv_buf_t instead of iovec * because Windows's WSABUF is not an iovec. */ - assert(sizeof(uv_buf_t) == sizeof(struct iovec)); - iov = (struct iovec*) &(req->bufs[req->write_index]); - iovcnt = req->nbufs - req->write_index; + iov = (struct iovec*) bufs; + iovcnt = nbufs; iovmax = uv__getiovmax(); @@ -837,8 +825,7 @@ static void uv__write(uv_stream_t* stream) { * Now do the actual writev. Note that we've been updating the pointers * inside the iov each time we write. So there is no need to offset it. */ - - if (req->send_handle) { + if (send_handle != NULL) { int fd_to_send; struct msghdr msg; struct cmsghdr *cmsg; @@ -847,12 +834,10 @@ static void uv__write(uv_stream_t* stream) { struct cmsghdr alias; } scratch; - if (uv__is_closing(req->send_handle)) { - err = UV_EBADF; - goto error; - } + if (uv__is_closing(send_handle)) + return UV_EBADF; - fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); + fd_to_send = uv__handle_fd((uv_handle_t*) send_handle); memset(&scratch, 0, sizeof(scratch)); @@ -882,44 +867,68 @@ static void uv__write(uv_stream_t* stream) { do n = sendmsg(uv__stream_fd(stream), &msg, 0); while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); - - /* Ensure the handle isn't sent again in case this is a partial write. */ - if (n >= 0) - req->send_handle = NULL; } else { do n = uv__writev(uv__stream_fd(stream), iov, iovcnt); while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); } - if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) { - err = UV__ERR(errno); - goto error; - } + if (n >= 0) + return n; - if (n >= 0 && uv__write_req_update(stream, req, n)) { - uv__write_req_finish(req); - return; /* TODO(bnoordhuis) Start trying to write the next request. */ - } + if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle)) + return UV_EAGAIN; - /* If this is a blocking stream, try again. */ - if (stream->flags & UV_HANDLE_BLOCKING_WRITES) - goto start; + return UV__ERR(errno); +} - /* We're not done. */ - uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); +static void uv__write(uv_stream_t* stream) { + QUEUE* q; + uv_write_t* req; + ssize_t n; - /* Notify select() thread about state change */ - uv__stream_osx_interrupt_select(stream); + assert(uv__stream_fd(stream) >= 0); + + for (;;) { + if (QUEUE_EMPTY(&stream->write_queue)) + return; + + q = QUEUE_HEAD(&stream->write_queue); + req = QUEUE_DATA(q, uv_write_t, queue); + assert(req->handle == stream); + + n = uv__try_write(stream, + &(req->bufs[req->write_index]), + req->nbufs - req->write_index, + req->send_handle); + + /* Ensure the handle isn't sent again in case this is a partial write. */ + if (n >= 0) { + req->send_handle = NULL; + if (uv__write_req_update(stream, req, n)) { + uv__write_req_finish(req); + return; /* TODO(bnoordhuis) Start trying to write the next request. */ + } + } else if (n != UV_EAGAIN) + break; + + /* If this is a blocking stream, try again. */ + if (stream->flags & UV_HANDLE_BLOCKING_WRITES) + continue; - return; + /* We're not done. */ + uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); + + /* Notify select() thread about state change */ + uv__stream_osx_interrupt_select(stream); + + return; + } -error: - req->error = err; + req->error = n; + // XXX(jwn): this must call uv__stream_flush_write_queue(stream, n) here, since we won't generate any more events uv__write_req_finish(req); uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); - if (!uv__io_active(&stream->io_watcher, POLLIN)) - uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); } @@ -1001,9 +1010,9 @@ uv_handle_type uv__handle_type(int fd) { static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { stream->flags |= UV_HANDLE_READ_EOF; stream->flags &= ~UV_HANDLE_READING; + stream->flags &= ~UV_HANDLE_READABLE; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); - if (!uv__io_active(&stream->io_watcher, POLLOUT)) - uv__handle_stop(stream); + uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); stream->read_cb(stream, UV_EOF, buf); } @@ -1188,12 +1197,12 @@ static void uv__read(uv_stream_t* stream) { #endif } else { /* Error. User should call uv_close(). */ + stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); stream->read_cb(stream, UV__ERR(errno), &buf); if (stream->flags & UV_HANDLE_READING) { stream->flags &= ~UV_HANDLE_READING; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); - if (!uv__io_active(&stream->io_watcher, POLLOUT)) - uv__handle_stop(stream); + uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); } } @@ -1276,6 +1285,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { req->cb = cb; stream->shutdown_req = req; stream->flags |= UV_HANDLE_SHUTTING; + stream->flags &= ~UV_HANDLE_WRITABLE; uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); uv__stream_osx_interrupt_select(stream); @@ -1390,14 +1400,9 @@ static void uv__stream_connect(uv_stream_t* stream) { } -int uv_write2(uv_write_t* req, - uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int empty_queue; - +static int uv__check_before_write(uv_stream_t* stream, + unsigned int nbufs, + uv_stream_t* send_handle) { assert(nbufs > 0); assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || @@ -1410,7 +1415,7 @@ int uv_write2(uv_write_t* req, if (!(stream->flags & UV_HANDLE_WRITABLE)) return UV_EPIPE; - if (send_handle) { + if (send_handle != NULL) { if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) return UV_EINVAL; @@ -1430,6 +1435,22 @@ int uv_write2(uv_write_t* req, #endif } + return 0; +} + +int uv_write2(uv_write_t* req, + uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb) { + int empty_queue; + int err; + + err = uv__check_before_write(stream, nbufs, send_handle); + if (err < 0) + return err; + /* It's legal for write_queue_size > 0 even when the write_queue is empty; * it means there are error-state requests in the write_completed_queue that * will touch up write_queue_size later, see also uv__write_req_finish(). @@ -1498,57 +1519,28 @@ int uv_write(uv_write_t* req, } -void uv_try_write_cb(uv_write_t* req, int status) { - /* Should not be called */ - abort(); -} - - int uv_try_write(uv_stream_t* stream, const uv_buf_t bufs[], unsigned int nbufs) { - int r; - int has_pollout; - size_t written; - size_t req_size; - uv_write_t req; + return uv_try_write2(stream, bufs, nbufs, NULL); +} + + +int uv_try_write2(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { + int err; /* Connecting or already writing some data */ if (stream->connect_req != NULL || stream->write_queue_size != 0) return UV_EAGAIN; - has_pollout = uv__io_active(&stream->io_watcher, POLLOUT); - - r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb); - if (r != 0) - return r; - - /* Remove not written bytes from write queue size */ - written = uv__count_bufs(bufs, nbufs); - if (req.bufs != NULL) - req_size = uv__write_req_size(&req); - else - req_size = 0; - written -= req_size; - stream->write_queue_size -= req_size; - - /* Unqueue request, regardless of immediateness */ - QUEUE_REMOVE(&req.queue); - uv__req_unregister(stream->loop, &req); - if (req.bufs != req.bufsml) - uv__free(req.bufs); - req.bufs = NULL; - - /* Do not poll for writable, if we wasn't before calling this */ - if (!has_pollout) { - uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); - uv__stream_osx_interrupt_select(stream); - } + err = uv__check_before_write(stream, nbufs, NULL); + if (err < 0) + return err; - if (written == 0 && req_size != 0) - return req.error < 0 ? req.error : UV_EAGAIN; - else - return written; + return uv__try_write(stream, bufs, nbufs, send_handle); } @@ -1587,8 +1579,7 @@ int uv_read_stop(uv_stream_t* stream) { stream->flags &= ~UV_HANDLE_READING; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); - if (!uv__io_active(&stream->io_watcher, POLLOUT)) - uv__handle_stop(stream); + uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); stream->read_cb = NULL; diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index d511c18b85e8ee..2bf297e5d966b7 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -865,3 +865,14 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, uv__free(addresses); } + + +#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L +size_t strnlen(const char* s, size_t maxlen) { + const char* end; + end = memchr(s, '\0', maxlen); + if (end == NULL) + return maxlen; + return end - s; +} +#endif diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c index 1a85d1d4fcd4df..c46450cc661270 100644 --- a/deps/uv/src/unix/thread.c +++ b/deps/uv/src/unix/thread.c @@ -107,8 +107,7 @@ int uv_barrier_wait(uv_barrier_t* barrier) { } last = (--b->out == 0); - if (!last) - uv_cond_signal(&b->cond); /* Not needed for last thread. */ + uv_cond_signal(&b->cond); uv_mutex_unlock(&b->mutex); return last; @@ -122,9 +121,10 @@ void uv_barrier_destroy(uv_barrier_t* barrier) { uv_mutex_lock(&b->mutex); assert(b->in == 0); - assert(b->out == 0); + while (b->out != 0) + uv_cond_wait(&b->cond, &b->mutex); - if (b->in != 0 || b->out != 0) + if (b->in != 0) abort(); uv_mutex_unlock(&b->mutex); @@ -168,7 +168,7 @@ void uv_barrier_destroy(uv_barrier_t* barrier) { * On Linux, threads created by musl have a much smaller stack than threads * created by glibc (80 vs. 2048 or 4096 kB.) Follow glibc for consistency. */ -static size_t thread_stack_size(void) { +size_t uv__thread_stack_size(void) { #if defined(__APPLE__) || defined(__linux__) struct rlimit lim; @@ -234,7 +234,7 @@ int uv_thread_create_ex(uv_thread_t* tid, attr = NULL; if (stack_size == 0) { - stack_size = thread_stack_size(); + stack_size = uv__thread_stack_size(); } else { pagesize = (size_t)getpagesize(); /* Round up to the nearest page boundary. */ diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c index 6f60abaadb02ef..9442cf16360e50 100644 --- a/deps/uv/src/unix/tty.c +++ b/deps/uv/src/unix/tty.c @@ -242,6 +242,24 @@ static void uv__tty_make_raw(struct termios* tio) { tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tio->c_cflag &= ~(CSIZE | PARENB); tio->c_cflag |= CS8; + + /* + * By default, most software expects a pending read to block until at + * least one byte becomes available. As per termio(7I), this requires + * setting the MIN and TIME parameters appropriately. + * + * As a somewhat unfortunate artifact of history, the MIN and TIME slots + * in the control character array overlap with the EOF and EOL slots used + * for canonical mode processing. Because the EOF character needs to be + * the ASCII EOT value (aka Control-D), it has the byte value 4. When + * switching to raw mode, this is interpreted as a MIN value of 4; i.e., + * reads will block until at least four bytes have been input. + * + * Other platforms with a distinct MIN slot like Linux and FreeBSD appear + * to default to a MIN value of 1, so we'll force that value here: + */ + tio->c_cc[VMIN] = 1; + tio->c_cc[VTIME] = 0; #else cfmakeraw(tio); #endif /* #ifdef __sun */ diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 7d699a16753c6b..49051c07c15491 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -32,8 +32,6 @@ #endif #include -#define UV__UDP_DGRAM_MAXSIZE (64 * 1024) - #if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP) # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #endif @@ -504,6 +502,28 @@ static int uv__set_reuse(int fd) { return 0; } +/* + * The Linux kernel suppresses some ICMP error messages by default for UDP + * sockets. Setting IP_RECVERR/IPV6_RECVERR on the socket enables full ICMP + * error reporting, hopefully resulting in faster failover to working name + * servers. + */ +static int uv__set_recverr(int fd, sa_family_t ss_family) { +#if defined(__linux__) + int yes; + + yes = 1; + if (ss_family == AF_INET) { + if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, &yes, sizeof(yes))) + return UV__ERR(errno); + } else if (ss_family == AF_INET6) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, &yes, sizeof(yes))) + return UV__ERR(errno); + } +#endif + return 0; +} + int uv__udp_bind(uv_udp_t* handle, const struct sockaddr* addr, @@ -514,7 +534,7 @@ int uv__udp_bind(uv_udp_t* handle, int fd; /* Check for bad flags. */ - if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR)) + if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | UV_UDP_LINUX_RECVERR)) return UV_EINVAL; /* Cannot set IPv6-only mode on non-IPv6 socket. */ @@ -530,6 +550,12 @@ int uv__udp_bind(uv_udp_t* handle, handle->io_watcher.fd = fd; } + if (flags & UV_UDP_LINUX_RECVERR) { + err = uv__set_recverr(fd, addr->sa_family); + if (err) + return err; + } + if (flags & UV_UDP_REUSEADDR) { err = uv__set_reuse(fd); if (err) diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index dd559a11d11b6a..e81ed79b0c551d 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -872,7 +872,11 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { } -#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */ +/* Also covers __clang__ and __INTEL_COMPILER. Disabled on Windows because + * threads have already been forcibly terminated by the operating system + * by the time destructors run, ergo, it's not safe to try to clean them up. + */ +#if defined(__GNUC__) && !defined(_WIN32) __attribute__((destructor)) #endif void uv_library_shutdown(void) { diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index a92912fdb1a72e..8a190bf8fa8c5a 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -68,6 +68,8 @@ extern int snprintf(char*, size_t, const char*, ...); #define uv__store_relaxed(p, v) do *p = v; while (0) #endif +#define UV__UDP_DGRAM_MAXSIZE (64 * 1024) + /* Handle flags. Some flags are specific to Windows or UNIX. */ enum { /* Used by all handles. */ @@ -106,8 +108,7 @@ enum { UV_HANDLE_TCP_KEEPALIVE = 0x02000000, UV_HANDLE_TCP_SINGLE_ACCEPT = 0x04000000, UV_HANDLE_TCP_ACCEPT_STATE_CHANGING = 0x08000000, - UV_HANDLE_TCP_SOCKET_CLOSED = 0x10000000, - UV_HANDLE_SHARED_TCP_SOCKET = 0x20000000, + UV_HANDLE_SHARED_TCP_SOCKET = 0x10000000, /* Only used by uv_udp_t handles. */ UV_HANDLE_UDP_PROCESSING = 0x01000000, diff --git a/deps/uv/src/win/atomicops-inl.h b/deps/uv/src/win/atomicops-inl.h index 52713cf305feb5..2f984c6db0b428 100644 --- a/deps/uv/src/win/atomicops-inl.h +++ b/deps/uv/src/win/atomicops-inl.h @@ -39,10 +39,11 @@ static char INLINE uv__atomic_exchange_set(char volatile* target) { return _InterlockedOr8(target, 1); } -#else /* GCC */ +#else /* GCC, Clang in mingw mode */ -/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ static inline char uv__atomic_exchange_set(char volatile* target) { +#if defined(__i386__) || defined(__x86_64__) + /* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ const char one = 1; char old_value; __asm__ __volatile__ ("lock xchgb %0, %1\n\t" @@ -50,6 +51,9 @@ static inline char uv__atomic_exchange_set(char volatile* target) { : "0"(one), "m"(*target) : "memory"); return old_value; +#else + return __sync_fetch_and_or(target, 1); +#endif } #endif diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 3ec984c83eb077..3a269da87a948b 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -105,7 +105,6 @@ int uv_translate_sys_error(int sys_errno) { case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; case WSAEINVAL: return UV_EINVAL; case WSAEPFNOSUPPORT: return UV_EINVAL; - case WSAESOCKTNOSUPPORT: return UV_EINVAL; case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; case ERROR_BUS_RESET: return UV_EIO; case ERROR_CRC: return UV_EIO; @@ -168,6 +167,7 @@ int uv_translate_sys_error(int sys_errno) { case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; case ERROR_INVALID_FUNCTION: return UV_EISDIR; case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; + case WSAESOCKTNOSUPPORT: return UV_ESOCKTNOSUPPORT; default: return UV_UNKNOWN; } } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index a083b5e82c8c42..674070400be419 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -1238,7 +1238,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) { uint64_t v; char* path; - path = req->path; + path = (char*)req->path; len = wcslen(req->file.pathw); ep = req->file.pathw + len; if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) { diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c index 87858590c8525a..9d37759606692e 100644 --- a/deps/uv/src/win/poll.c +++ b/deps/uv/src/win/poll.c @@ -488,7 +488,8 @@ static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) { assert(handle->type == UV_POLL); assert(!(handle->flags & UV_HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0); + assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT | + UV_PRIORITIZED)) == 0); handle->events = events; handle->poll_cb = cb; diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 73543c6ed987ce..4038fbfd290d1a 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -642,7 +642,7 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { assert(r==nb); B[nb] = L'\0'; - while (1) { + for (;;) { wchar_t AA = *A++; wchar_t BB = *B++; if (AA < BB) { diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c index ebb5fe5cb79d04..abf477f64421d5 100644 --- a/deps/uv/src/win/stream.c +++ b/deps/uv/src/win/stream.c @@ -188,6 +188,16 @@ int uv_try_write(uv_stream_t* stream, } +int uv_try_write2(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { + if (send_handle != NULL) + return UV_EAGAIN; + return uv_try_write(stream, bufs, nbufs); +} + + int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { uv_loop_t* loop = handle->loop; diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 517700e66d81b9..cf2dbd85fdbb05 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -236,12 +236,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { - closesocket(handle->socket); - handle->socket = INVALID_SOCKET; - handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } + assert(handle->socket == INVALID_SOCKET); if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) { @@ -599,6 +594,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { } } + /* If this flag is set, we already made this listen call in xfer. */ if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && listen(handle->socket, backlog) == SOCKET_ERROR) { return WSAGetLastError(); @@ -769,7 +765,7 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) { } // Check if Windows version is 10.0.16299 or later -static int uv__is_fast_loopback_fail_supported() { +static int uv__is_fast_loopback_fail_supported(void) { OSVERSIONINFOW os_info; if (!pRtlGetVersion) return 0; @@ -1024,6 +1020,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, */ err = WSAECONNRESET; } + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), @@ -1105,6 +1102,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, * Unix. */ err = WSAECONNRESET; } + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(err), @@ -1158,9 +1156,14 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, } handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); + if (handle->stream.conn.write_reqs_pending == 0) { + if (handle->flags & UV_HANDLE_CLOSING) { + closesocket(handle->socket); + handle->socket = INVALID_SOCKET; + } + if (handle->stream.conn.shutdown_req != NULL) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } } DECREASE_PENDING_REQ_COUNT(handle); @@ -1336,7 +1339,7 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { if (handle->socket != INVALID_SOCKET) { err = uv__tcp_nodelay(handle, handle->socket, enable); if (err) - return err; + return uv_translate_sys_error(err); } if (enable) { @@ -1355,7 +1358,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { if (handle->socket != INVALID_SOCKET) { err = uv__tcp_keepalive(handle, handle->socket, enable, delay); if (err) - return err; + return uv_translate_sys_error(err); } if (enable) { @@ -1402,9 +1405,24 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { } -static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) { - SOCKET socket = tcp->socket; +static void uv_tcp_try_cancel_reqs(uv_tcp_t* tcp) { + SOCKET socket; int non_ifs_lsp; + int reading; + int writing; + + socket = tcp->socket; + reading = tcp->flags & UV_HANDLE_READING; + writing = tcp->stream.conn.write_reqs_pending > 0; + if (!reading && !writing) + return; + + /* TODO: in libuv v2, keep explicit track of write_reqs, so we can cancel + * them each explicitly with CancelIoEx (like unix). */ + if (reading) + CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped); + if (writing) + CancelIo((HANDLE) socket); /* Check if we have any non-IFS LSPs stacked on top of TCP */ non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 : @@ -1424,71 +1442,41 @@ static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) { NULL, NULL) != 0) { /* Failed. We can't do CancelIo. */ - return -1; + return; } } assert(socket != 0 && socket != INVALID_SOCKET); - if (!CancelIo((HANDLE) socket)) { - return GetLastError(); + if (socket != tcp->socket) { + if (reading) + CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped); + if (writing) + CancelIo((HANDLE) socket); } - - /* It worked. */ - return 0; } void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { - int close_socket = 1; - - if (tcp->flags & UV_HANDLE_READ_PENDING) { - /* In order for winsock to do a graceful close there must not be any any - * pending reads, or the socket must be shut down for writing */ - if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) { - /* Just do shutdown on non-shared sockets, which ensures graceful close. */ - shutdown(tcp->socket, SD_SEND); - - } else if (uv_tcp_try_cancel_io(tcp) == 0) { - /* In case of a shared socket, we try to cancel all outstanding I/O,. If - * that works, don't close the socket yet - wait for the read req to - * return and close the socket in uv_tcp_endgame. */ - close_socket = 0; - - } else { - /* When cancelling isn't possible - which could happen when an LSP is - * present on an old Windows version, we will have to close the socket - * with a read pending. That is not nice because trailing sent bytes may - * not make it to the other side. */ + if (tcp->flags & UV_HANDLE_CONNECTION) { + uv_tcp_try_cancel_reqs(tcp); + if (tcp->flags & UV_HANDLE_READING) { + uv_read_stop((uv_stream_t*) tcp); } - - } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - tcp->tcp.serv.accept_reqs != NULL) { - /* Under normal circumstances closesocket() will ensure that all pending - * accept reqs are canceled. However, when the socket is shared the - * presence of another reference to the socket in another process will keep - * the accept reqs going, so we have to ensure that these are canceled. */ - if (uv_tcp_try_cancel_io(tcp) != 0) { - /* When cancellation is not possible, there is another option: we can - * close the incoming sockets, which will also cancel the accept - * operations. However this is not cool because we might inadvertently - * close a socket that just accepted a new connection, which will cause - * the connection to be aborted. */ + } else { + if (tcp->tcp.serv.accept_reqs != NULL) { + /* First close the incoming sockets to cancel the accept operations before + * we free their resources. */ unsigned int i; for (i = 0; i < uv_simultaneous_server_accepts; i++) { uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i]; - if (req->accept_socket != INVALID_SOCKET && - !HasOverlappedIoCompleted(&req->u.io.overlapped)) { + if (req->accept_socket != INVALID_SOCKET) { closesocket(req->accept_socket); req->accept_socket = INVALID_SOCKET; } } } - } - - if (tcp->flags & UV_HANDLE_READING) { - tcp->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, tcp); + assert(!(tcp->flags & UV_HANDLE_READING)); } if (tcp->flags & UV_HANDLE_LISTENING) { @@ -1496,10 +1484,15 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { DECREASE_ACTIVE_COUNT(loop, tcp); } - if (close_socket) { + /* If any overlapped req failed to cancel, calling `closesocket` now would + * cause Win32 to send an RST packet. Try to avoid that for writes, if + * possibly applicable, by waiting to process the completion notifications + * first (which typically should be cancellations). There's not much we can + * do about canceled reads, which also will generate an RST packet. */ + if (!(tcp->flags & UV_HANDLE_CONNECTION) || + tcp->stream.conn.write_reqs_pending == 0) { closesocket(tcp->socket); tcp->socket = INVALID_SOCKET; - tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; } tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 68ca728aa5c9cc..3043f2da88e74a 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -284,7 +284,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { handle->flags &= ~UV_HANDLE_ZERO_READ; handle->recv_buffer = uv_buf_init(NULL, 0); - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); + handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &handle->recv_buffer); if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) { handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); return; @@ -501,7 +501,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, /* Do a nonblocking receive. * TODO: try to read multiple datagrams at once. FIONREAD maybe? */ buf = uv_buf_init(NULL, 0); - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); + handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf); if (buf.base == NULL || buf.len == 0) { handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); goto done; diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index aad8f1a15e9cb6..88602c7ee8623f 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -1664,26 +1664,33 @@ int uv_os_unsetenv(const char* name) { int uv_os_gethostname(char* buffer, size_t* size) { - char buf[UV_MAXHOSTNAMESIZE]; + WCHAR buf[UV_MAXHOSTNAMESIZE]; size_t len; + char* utf8_str; + int convert_result; if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; uv__once_init(); /* Initialize winsock */ - if (gethostname(buf, sizeof(buf)) != 0) + if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) return uv_translate_sys_error(WSAGetLastError()); - buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ - len = strlen(buf); + convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str); + if (convert_result != 0) + return convert_result; + + len = strlen(utf8_str); if (len >= *size) { *size = len + 1; + uv__free(utf8_str); return UV_ENOBUFS; } - memcpy(buffer, buf, len + 1); + memcpy(buffer, utf8_str, len + 1); + uv__free(utf8_str); *size = len; return 0; } diff --git a/deps/uv/test/benchmark-async-pummel.c b/deps/uv/test/benchmark-async-pummel.c index 119ae5eee5a28c..49660a6f5755c0 100644 --- a/deps/uv/test/benchmark-async-pummel.c +++ b/deps/uv/test/benchmark-async-pummel.c @@ -68,7 +68,7 @@ static int test_async_pummel(int nthreads) { int i; tids = calloc(nthreads, sizeof(tids[0])); - ASSERT(tids != NULL); + ASSERT_NOT_NULL(tids); ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb)); ACCESS_ONCE(const char*, handle.data) = running; diff --git a/deps/uv/test/benchmark-async.c b/deps/uv/test/benchmark-async.c index e44165f2b81485..5167ecbd758d7a 100644 --- a/deps/uv/test/benchmark-async.c +++ b/deps/uv/test/benchmark-async.c @@ -79,7 +79,7 @@ static int test_async(int nthreads) { int i; threads = calloc(nthreads, sizeof(threads[0])); - ASSERT(threads != NULL); + ASSERT_NOT_NULL(threads); for (i = 0; i < nthreads; i++) { ctx = threads + i; diff --git a/deps/uv/test/benchmark-million-async.c b/deps/uv/test/benchmark-million-async.c index 5395ed54bab5c0..937a12f81e64be 100644 --- a/deps/uv/test/benchmark-million-async.c +++ b/deps/uv/test/benchmark-million-async.c @@ -86,7 +86,7 @@ BENCHMARK_IMPL(million_async) { timeout = 5000; container = malloc(sizeof(*container)); - ASSERT(container != NULL); + ASSERT_NOT_NULL(container); container->async_events = 0; container->handles_seen = 0; diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c index 60a308bef13d40..ef25c2052d6f66 100644 --- a/deps/uv/test/benchmark-million-timers.c +++ b/deps/uv/test/benchmark-million-timers.c @@ -49,7 +49,7 @@ BENCHMARK_IMPL(million_timers) { int i; timers = malloc(NUM_TIMERS * sizeof(timers[0])); - ASSERT(timers != NULL); + ASSERT_NOT_NULL(timers); loop = uv_default_loop(); timeout = 0; diff --git a/deps/uv/test/benchmark-multi-accept.c b/deps/uv/test/benchmark-multi-accept.c index 5a186233f580d9..86b7da5acd158a 100644 --- a/deps/uv/test/benchmark-multi-accept.c +++ b/deps/uv/test/benchmark-multi-accept.c @@ -114,7 +114,7 @@ static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) { buf = uv_buf_init("PING", 4); sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe); pc = calloc(1, sizeof(*pc)); - ASSERT(pc != NULL); + ASSERT_NOT_NULL(pc); if (ipc_pipe->type == UV_TCP) ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle)); @@ -295,7 +295,7 @@ static void sv_connection_cb(uv_stream_t* server_handle, int status) { ASSERT(status == 0); storage = malloc(sizeof(*storage)); - ASSERT(storage != NULL); + ASSERT_NOT_NULL(storage); if (server_handle->type == UV_TCP) ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage)); @@ -372,8 +372,8 @@ static int test_tcp(unsigned int num_servers, unsigned int num_clients) { servers = calloc(num_servers, sizeof(servers[0])); clients = calloc(num_clients, sizeof(clients[0])); - ASSERT(servers != NULL); - ASSERT(clients != NULL); + ASSERT_NOT_NULL(servers); + ASSERT_NOT_NULL(clients); /* We're making the assumption here that from the perspective of the * OS scheduler, threads are functionally equivalent to and interchangeable diff --git a/deps/uv/test/benchmark-pound.c b/deps/uv/test/benchmark-pound.c index 79f36345037cd4..830bc554b34348 100644 --- a/deps/uv/test/benchmark-pound.c +++ b/deps/uv/test/benchmark-pound.c @@ -114,11 +114,11 @@ static void connect_cb(uv_connect_t* req, int status) { return; } - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); conn = (conn_rec*)req->data; - ASSERT(conn != NULL); + ASSERT_NOT_NULL(conn); #if DEBUG printf("connect_cb %d\n", conn->i); @@ -137,7 +137,7 @@ static void connect_cb(uv_connect_t* req, int status) { static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { - ASSERT(stream != NULL); + ASSERT_NOT_NULL(stream); #if DEBUG printf("read_cb %d\n", p->i); @@ -161,7 +161,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { static void close_cb(uv_handle_t* handle) { conn_rec* p = (conn_rec*)handle->data; - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); closed_streams++; #if DEBUG diff --git a/deps/uv/test/benchmark-tcp-write-batch.c b/deps/uv/test/benchmark-tcp-write-batch.c index 96921b70db57ef..16aa72f6bf73c8 100644 --- a/deps/uv/test/benchmark-tcp-write-batch.c +++ b/deps/uv/test/benchmark-tcp-write-batch.c @@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) { static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); write_cb_called++; } @@ -103,7 +103,7 @@ BENCHMARK_IMPL(tcp_write_batch) { int r; write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS); - ASSERT(write_reqs != NULL); + ASSERT_NOT_NULL(write_reqs); /* Prepare the data to write out. */ for (i = 0; i < NUM_WRITE_REQS; i++) { diff --git a/deps/uv/test/benchmark-udp-pummel.c b/deps/uv/test/benchmark-udp-pummel.c index 68a2373d781fc3..1a2205702603e0 100644 --- a/deps/uv/test/benchmark-udp-pummel.c +++ b/deps/uv/test/benchmark-udp-pummel.c @@ -72,7 +72,7 @@ static void alloc_cb(uv_handle_t* handle, static void send_cb(uv_udp_send_t* req, int status) { struct sender_state* s; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); if (status != 0) { ASSERT(status == UV_ECANCELED); @@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle, static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -179,11 +179,11 @@ static int pummel(unsigned int n_senders, uv_unref((uv_handle_t*)&s->udp_handle); } - bufs[0] = uv_buf_init(EXPECTED + 0, 10); - bufs[1] = uv_buf_init(EXPECTED + 10, 10); - bufs[2] = uv_buf_init(EXPECTED + 20, 10); - bufs[3] = uv_buf_init(EXPECTED + 30, 10); - bufs[4] = uv_buf_init(EXPECTED + 40, 5); + bufs[0] = uv_buf_init(&EXPECTED[0], 10); + bufs[1] = uv_buf_init(&EXPECTED[10], 10); + bufs[2] = uv_buf_init(&EXPECTED[20], 10); + bufs[3] = uv_buf_init(&EXPECTED[30], 10); + bufs[4] = uv_buf_init(&EXPECTED[40], 5); for (i = 0; i < n_senders; i++) { struct sender_state* s = senders + i; diff --git a/deps/uv/test/blackhole-server.c b/deps/uv/test/blackhole-server.c index 9b21d1e0e07279..0a8758e1a1733b 100644 --- a/deps/uv/test/blackhole-server.c +++ b/deps/uv/test/blackhole-server.c @@ -47,7 +47,7 @@ static void connection_cb(uv_stream_t* stream, int status) { ASSERT(stream == (uv_stream_t*)&tcp_server); conn = malloc(sizeof *conn); - ASSERT(conn != NULL); + ASSERT_NOT_NULL(conn); r = uv_tcp_init(stream->loop, &conn->handle); ASSERT(r == 0); diff --git a/deps/uv/test/dns-server.c b/deps/uv/test/dns-server.c index 80052c703983b0..f8ca87f227e8e2 100644 --- a/deps/uv/test/dns-server.c +++ b/deps/uv/test/dns-server.c @@ -280,7 +280,7 @@ static void on_connection(uv_stream_t* server, int status) { ASSERT(status == 0); handle = (dnshandle*) malloc(sizeof *handle); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); /* initialize read buffer state */ handle->state.prevbuf_ptr = 0; diff --git a/deps/uv/test/echo-server.c b/deps/uv/test/echo-server.c index 69d0abc980bc32..058c9925475c94 100644 --- a/deps/uv/test/echo-server.c +++ b/deps/uv/test/echo-server.c @@ -65,25 +65,35 @@ static void after_write(uv_write_t* req, int status) { static void after_shutdown(uv_shutdown_t* req, int status) { + ASSERT_EQ(status, 0); uv_close((uv_handle_t*) req->handle, on_close); free(req); } +static void on_shutdown(uv_shutdown_t* req, int status) { + ASSERT_EQ(status, 0); + free(req); +} + + static void after_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { int i; write_req_t *wr; uv_shutdown_t* sreq; + int shutdown = 0; if (nread < 0) { /* Error or EOF */ - ASSERT(nread == UV_EOF); + ASSERT_EQ(nread, UV_EOF); free(buf->base); sreq = malloc(sizeof* sreq); - ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown)); + if (uv_is_writable(handle)) { + ASSERT_EQ(0, uv_shutdown(sreq, handle, after_shutdown)); + } return; } @@ -96,29 +106,42 @@ static void after_read(uv_stream_t* handle, /* * Scan for the letter Q which signals that we should quit the server. * If we get QS it means close the stream. + * If we get QSS it means shutdown the stream. + * If we get QSH it means disable linger before close the socket. */ - if (!server_closed) { - for (i = 0; i < nread; i++) { - if (buf->base[i] == 'Q') { - if (i + 1 < nread && buf->base[i + 1] == 'S') { - free(buf->base); - uv_close((uv_handle_t*)handle, on_close); - return; - } else { - uv_close(server, on_server_close); - server_closed = 1; - } + for (i = 0; i < nread; i++) { + if (buf->base[i] == 'Q') { + if (i + 1 < nread && buf->base[i + 1] == 'S') { + int reset = 0; + if (i + 2 < nread && buf->base[i + 2] == 'S') + shutdown = 1; + if (i + 2 < nread && buf->base[i + 2] == 'H') + reset = 1; + if (reset && handle->type == UV_TCP) + ASSERT_EQ(0, uv_tcp_close_reset((uv_tcp_t*) handle, on_close)); + else if (shutdown) + break; + else + uv_close((uv_handle_t*) handle, on_close); + free(buf->base); + return; + } else if (!server_closed) { + uv_close(server, on_server_close); + server_closed = 1; } } } wr = (write_req_t*) malloc(sizeof *wr); - ASSERT(wr != NULL); + ASSERT_NOT_NULL(wr); wr->buf = uv_buf_init(buf->base, nread); if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) { FATAL("uv_write failed"); } + + if (shutdown) + ASSERT_EQ(0, uv_shutdown(malloc(sizeof* sreq), handle, on_shutdown)); } @@ -155,14 +178,14 @@ static void on_connection(uv_stream_t* server, int status) { switch (serverType) { case TCP: stream = malloc(sizeof(uv_tcp_t)); - ASSERT(stream != NULL); + ASSERT_NOT_NULL(stream); r = uv_tcp_init(loop, (uv_tcp_t*)stream); ASSERT(r == 0); break; case PIPE: stream = malloc(sizeof(uv_pipe_t)); - ASSERT(stream != NULL); + ASSERT_NOT_NULL(stream); r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0); ASSERT(r == 0); break; @@ -197,7 +220,7 @@ static uv_udp_send_t* send_alloc(void) { } static void on_send(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); req->data = send_freelist; send_freelist = req; @@ -220,7 +243,7 @@ static void on_recv(uv_udp_t* handle, ASSERT(addr->sa_family == AF_INET); req = send_alloc(); - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); sndbuf = uv_buf_init(rcvbuf->base, nread); ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send)); } diff --git a/deps/uv/test/run-benchmarks.c b/deps/uv/test/run-benchmarks.c index 980c9be8c12aa6..2b343da4c91731 100644 --- a/deps/uv/test/run-benchmarks.c +++ b/deps/uv/test/run-benchmarks.c @@ -28,6 +28,16 @@ /* Actual benchmarks and helpers are defined in benchmark-list.h */ #include "benchmark-list.h" +#ifdef __MVS__ +#include "zos-base.h" +/* Initialize environment and zoslib */ +__attribute__((constructor)) void init() { + zoslib_config_t config; + init_zoslib_config(&config); + init_zoslib(config); +} +#endif + static int maybe_run_test(int argc, char **argv); @@ -44,8 +54,6 @@ int main(int argc, char **argv) { fflush(stderr); return EXIT_FAILURE; } - - return EXIT_SUCCESS; } diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index fc8a79a9eb9019..5e53aaa80b17ce 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -36,6 +36,16 @@ /* Actual tests and helpers are defined in test-list.h */ #include "test-list.h" +#ifdef __MVS__ +#include "zos-base.h" +/* Initialize environment and zoslib */ +__attribute__((constructor)) void init() { + zoslib_config_t config; + init_zoslib_config(&config); + init_zoslib(config); +} +#endif + int ipc_helper(int listen_after_write); int ipc_helper_heavy_traffic_deadlock_bug(void); int ipc_helper_tcp_connection(void); @@ -153,7 +163,7 @@ static int maybe_run_test(int argc, char **argv) { if (strcmp(argv[1], "spawn_helper4") == 0) { notify_parent_process(); /* Never surrender, never return! */ - while (1) uv_sleep(10000); + for (;;) uv_sleep(10000); } if (strcmp(argv[1], "spawn_helper5") == 0) { @@ -198,7 +208,7 @@ static int maybe_run_test(int argc, char **argv) { /* Test if the test value from the parent is still set */ test = getenv("ENV_TEST"); - ASSERT(test != NULL); + ASSERT_NOT_NULL(test); r = fprintf(stdout, "%s", test); ASSERT(r > 0); diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c index b7ca1f857ec1e4..a13648bc883878 100644 --- a/deps/uv/test/runner-unix.c +++ b/deps/uv/test/runner-unix.c @@ -197,7 +197,7 @@ static void* dowait(void* data) { process_info_t* p; for (i = 0; i < args->n; i++) { - p = (process_info_t*)(args->vec + i * sizeof(process_info_t)); + p = &args->vec[i]; if (p->terminated) continue; r = waitpid(p->pid, &p->status, 0); if (r < 0) { @@ -323,7 +323,7 @@ int process_wait(process_info_t* vec, int n, int timeout) { } else { /* Timeout. Kill all the children. */ for (i = 0; i < n; i++) { - p = (process_info_t*)(vec + i * sizeof(process_info_t)); + p = &vec[i]; kill(p->pid, SIGTERM); } retval = -2; diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c index bb50b43b304ab6..789108275cda11 100644 --- a/deps/uv/test/runner.c +++ b/deps/uv/test/runner.c @@ -98,8 +98,8 @@ int run_tests(int benchmark_output) { skip = (actual > 0 && 0 == strcmp(TASKS[0].task_name, "platform_output")); qsort(TASKS + skip, actual - skip, sizeof(TASKS[0]), compare_task); - fprintf(stderr, "1..%d\n", total); - fflush(stderr); + fprintf(stdout, "1..%d\n", total); + fflush(stdout); /* Run all tests. */ passed = 0; @@ -156,8 +156,8 @@ void log_tap_result(int test_count, reason[0] = '\0'; } - fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason); - fflush(stderr); + fprintf(stdout, "%s %d - %s%s%s\n", result, test_count, test, directive, reason); + fflush(stdout); } @@ -307,28 +307,28 @@ int run_test(const char* test, /* Show error and output from processes if the test failed. */ if ((status != TEST_OK && status != TEST_SKIP) || task->show_output) { if (strlen(errmsg) > 0) - fprintf(stderr, "# %s\n", errmsg); - fprintf(stderr, "# "); - fflush(stderr); + fprintf(stdout, "# %s\n", errmsg); + fprintf(stdout, "# "); + fflush(stdout); for (i = 0; i < process_count; i++) { switch (process_output_size(&processes[i])) { case -1: - fprintf(stderr, "Output from process `%s`: (unavailable)\n", + fprintf(stdout, "Output from process `%s`: (unavailable)\n", process_get_name(&processes[i])); - fflush(stderr); + fflush(stdout); break; case 0: - fprintf(stderr, "Output from process `%s`: (no output)\n", + fprintf(stdout, "Output from process `%s`: (no output)\n", process_get_name(&processes[i])); - fflush(stderr); + fflush(stdout); break; default: - fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i])); - fflush(stderr); - process_copy_output(&processes[i], stderr); + fprintf(stdout, "Output from process `%s`:\n", process_get_name(&processes[i])); + fflush(stdout); + process_copy_output(&processes[i], stdout); break; } } @@ -337,18 +337,18 @@ int run_test(const char* test, } else if (benchmark_output) { switch (process_output_size(main_proc)) { case -1: - fprintf(stderr, "%s: (unavailable)\n", test); - fflush(stderr); + fprintf(stdout, "%s: (unavailable)\n", test); + fflush(stdout); break; case 0: - fprintf(stderr, "%s: (no output)\n", test); - fflush(stderr); + fprintf(stdout, "%s: (no output)\n", test); + fflush(stdout); break; default: for (i = 0; i < process_count; i++) { - process_copy_output(&processes[i], stderr); + process_copy_output(&processes[i], stdout); } break; } @@ -378,8 +378,8 @@ int run_test_part(const char* test, const char* part) { } } - fprintf(stderr, "No test part with that name: %s:%s\n", test, part); - fflush(stderr); + fprintf(stdout, "No test part with that name: %s:%s\n", test, part); + fflush(stdout); return 255; } diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 4e7e2f07f570d3..a02c8931b50f2f 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -52,6 +52,7 @@ #define TEST_PORT 9123 #define TEST_PORT_2 9124 +#define TEST_PORT_3 9125 #ifdef _WIN32 # define TEST_PIPENAME "\\\\?\\pipe\\uv-test" diff --git a/deps/uv/test/test-active.c b/deps/uv/test/test-active.c index b17bd1760188b4..384389561a79e8 100644 --- a/deps/uv/test/test-active.c +++ b/deps/uv/test/test-active.c @@ -30,7 +30,7 @@ static int close_cb_called = 0; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c index 6f5351bf1586b0..619be620e3e916 100644 --- a/deps/uv/test/test-async.c +++ b/deps/uv/test/test-async.c @@ -70,7 +70,7 @@ static void thread_cb(void *arg) { static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c index 1871e7e98196d1..a5195c7b7f3dd1 100644 --- a/deps/uv/test/test-callback-stack.c +++ b/deps/uv/test/test-callback-stack.c @@ -48,7 +48,7 @@ static int shutdown_cb_called = 0; static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { buf->len = size; buf->base = malloc(size); - ASSERT(buf->base != NULL); + ASSERT_NOT_NULL(buf->base); } diff --git a/deps/uv/test/test-close-order.c b/deps/uv/test/test-close-order.c index 2b24f6d6579163..c2fd6c3d0dec16 100644 --- a/deps/uv/test/test-close-order.c +++ b/deps/uv/test/test-close-order.c @@ -32,7 +32,7 @@ static uv_timer_t timer_handle2; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-default-loop-close.c b/deps/uv/test/test-default-loop-close.c index fd11cfa8c1285a..51e1e7dc23bffa 100644 --- a/deps/uv/test/test-default-loop-close.c +++ b/deps/uv/test/test-default-loop-close.c @@ -37,7 +37,7 @@ TEST_IMPL(default_loop_close) { uv_timer_t timer_handle; loop = uv_default_loop(); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); ASSERT(0 == uv_timer_init(loop, &timer_handle)); ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); @@ -46,7 +46,7 @@ TEST_IMPL(default_loop_close) { ASSERT(0 == uv_loop_close(loop)); loop = uv_default_loop(); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); ASSERT(0 == uv_timer_init(loop, &timer_handle)); ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c index 513e69bd5b7d23..88b31e26903f09 100644 --- a/deps/uv/test/test-delayed-accept.c +++ b/deps/uv/test/test-delayed-accept.c @@ -37,7 +37,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); free(handle); @@ -50,8 +50,8 @@ static void do_accept(uv_timer_t* timer_handle) { uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle); int r; - ASSERT(timer_handle != NULL); - ASSERT(accepted_handle != NULL); + ASSERT_NOT_NULL(timer_handle); + ASSERT_NOT_NULL(accepted_handle); r = uv_tcp_init(uv_default_loop(), accepted_handle); ASSERT(r == 0); @@ -82,7 +82,7 @@ static void connection_cb(uv_stream_t* tcp, int status) { ASSERT(status == 0); timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle); - ASSERT(timer_handle != NULL); + ASSERT_NOT_NULL(timer_handle); /* Accept the client after 1 second */ r = uv_timer_init(uv_default_loop(), timer_handle); @@ -103,7 +103,7 @@ static void start_server(void) { int r; ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - ASSERT(server != NULL); + ASSERT_NOT_NULL(server); r = uv_tcp_init(uv_default_loop(), server); ASSERT(r == 0); @@ -125,7 +125,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { if (nread >= 0) { ASSERT(nread == 0); } else { - ASSERT(tcp != NULL); + ASSERT_NOT_NULL(tcp); ASSERT(nread == UV_EOF); uv_close((uv_handle_t*)tcp, close_cb); } @@ -135,7 +135,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { static void connect_cb(uv_connect_t* req, int status) { int r; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); /* Not that the server will send anything, but otherwise we'll never know @@ -156,8 +156,8 @@ static void client_connect(void) { int r; ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(client != NULL); - ASSERT(connect_req != NULL); + ASSERT_NOT_NULL(client); + ASSERT_NOT_NULL(connect_req); r = uv_tcp_init(uv_default_loop(), client); ASSERT(r == 0); diff --git a/deps/uv/test/test-dlerror.c b/deps/uv/test/test-dlerror.c index 42ad68828626b1..a436ec016bfec8 100644 --- a/deps/uv/test/test-dlerror.c +++ b/deps/uv/test/test-dlerror.c @@ -34,26 +34,26 @@ TEST_IMPL(dlerror) { lib.errmsg = NULL; lib.handle = NULL; msg = uv_dlerror(&lib); - ASSERT(msg != NULL); - ASSERT(strstr(msg, dlerror_no_error) != NULL); + ASSERT_NOT_NULL(msg); + ASSERT_NOT_NULL(strstr(msg, dlerror_no_error)); r = uv_dlopen(path, &lib); ASSERT(r == -1); msg = uv_dlerror(&lib); - ASSERT(msg != NULL); + ASSERT_NOT_NULL(msg); #if !defined(__OpenBSD__) && !defined(__QNX__) - ASSERT(strstr(msg, path) != NULL); + ASSERT_NOT_NULL(strstr(msg, path)); #endif - ASSERT(strstr(msg, dlerror_no_error) == NULL); + ASSERT_NULL(strstr(msg, dlerror_no_error)); /* Should return the same error twice in a row. */ msg = uv_dlerror(&lib); - ASSERT(msg != NULL); + ASSERT_NOT_NULL(msg); #if !defined(__OpenBSD__) && !defined(__QNX__) - ASSERT(strstr(msg, path) != NULL); + ASSERT_NOT_NULL(strstr(msg, path)); #endif - ASSERT(strstr(msg, dlerror_no_error) == NULL); + ASSERT_NULL(strstr(msg, dlerror_no_error)); uv_dlclose(&lib); diff --git a/deps/uv/test/test-error.c b/deps/uv/test/test-error.c index 35d108a4a1f768..f0fb864607f36c 100644 --- a/deps/uv/test/test-error.c +++ b/deps/uv/test/test-error.c @@ -50,13 +50,13 @@ TEST_IMPL(error_message) { return 0; } - ASSERT(strstr(uv_strerror(UV_EINVAL), "Success") == NULL); + ASSERT_NULL(strstr(uv_strerror(UV_EINVAL), "Success")); ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0); ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0); - ASSERT(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success") == NULL); - ASSERT(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337") != NULL); - ASSERT(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337") != NULL); + ASSERT_NULL(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success")); + ASSERT_NOT_NULL(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337")); + ASSERT_NOT_NULL(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337")); return 0; } diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index 0992d5989e421b..ec163868f49925 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -118,7 +118,7 @@ static void touch_file(const char* name) { } static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -337,7 +337,7 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename, static void timer_cb_close_handle(uv_timer_t* timer) { uv_handle_t* handle; - ASSERT(timer != NULL); + ASSERT_NOT_NULL(timer); handle = timer->data; uv_close((uv_handle_t*)timer, NULL); @@ -758,7 +758,7 @@ TEST_IMPL(fs_event_watch_file_root_dir) { const char* sys_drive = getenv("SystemDrive"); char path[] = "\\\\?\\X:\\bootsect.bak"; - ASSERT(sys_drive != NULL); + ASSERT_NOT_NULL(sys_drive); strncpy(path + sizeof("\\\\?\\") - 1, sys_drive, 1); loop = uv_default_loop(); @@ -1072,7 +1072,7 @@ static void timer_cb_nop(uv_timer_t* handle) { } static void fs_event_error_report_close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; /* handle is allocated on-stack, no need to free it */ diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c index 9dfd5fdd6aa282..76fe6fc3957192 100644 --- a/deps/uv/test/test-fs-poll.c +++ b/deps/uv/test/test-fs-poll.c @@ -105,8 +105,8 @@ static void poll_cb(uv_fs_poll_t* handle, ASSERT(handle == &poll_handle); ASSERT(1 == uv_is_active((uv_handle_t*) handle)); - ASSERT(prev != NULL); - ASSERT(curr != NULL); + ASSERT_NOT_NULL(prev); + ASSERT_NOT_NULL(curr); switch (poll_cb_called++) { case 0: diff --git a/deps/uv/test/test-fs-readdir.c b/deps/uv/test/test-fs-readdir.c index cccaa7438baabc..41e1d373ca89a1 100644 --- a/deps/uv/test/test-fs-readdir.c +++ b/deps/uv/test/test-fs-readdir.c @@ -77,7 +77,7 @@ static void empty_opendir_cb(uv_fs_t* req) { ASSERT(req == &opendir_req); ASSERT(req->fs_type == UV_FS_OPENDIR); ASSERT(req->result == 0); - ASSERT(req->ptr != NULL); + ASSERT_NOT_NULL(req->ptr); dir = req->ptr; dir->dirents = dirents; dir->nentries = ARRAY_SIZE(dirents); @@ -118,7 +118,7 @@ TEST_IMPL(fs_readdir_empty_dir) { ASSERT(r == 0); ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); ASSERT(opendir_req.result == 0); - ASSERT(opendir_req.ptr != NULL); + ASSERT_NOT_NULL(opendir_req.ptr); dir = opendir_req.ptr; uv_fs_req_cleanup(&opendir_req); @@ -171,7 +171,7 @@ static void non_existing_opendir_cb(uv_fs_t* req) { ASSERT(req == &opendir_req); ASSERT(req->fs_type == UV_FS_OPENDIR); ASSERT(req->result == UV_ENOENT); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); uv_fs_req_cleanup(req); ++non_existing_opendir_cb_count; @@ -191,7 +191,7 @@ TEST_IMPL(fs_readdir_non_existing_dir) { ASSERT(r == UV_ENOENT); ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); ASSERT(opendir_req.result == UV_ENOENT); - ASSERT(opendir_req.ptr == NULL); + ASSERT_NULL(opendir_req.ptr); uv_fs_req_cleanup(&opendir_req); /* Fill the req to ensure that required fields are cleaned up. */ @@ -223,7 +223,7 @@ static void file_opendir_cb(uv_fs_t* req) { ASSERT(req == &opendir_req); ASSERT(req->fs_type == UV_FS_OPENDIR); ASSERT(req->result == UV_ENOTDIR); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); uv_fs_req_cleanup(req); ++file_opendir_cb_count; @@ -247,7 +247,7 @@ TEST_IMPL(fs_readdir_file) { ASSERT(r == UV_ENOTDIR); ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); ASSERT(opendir_req.result == UV_ENOTDIR); - ASSERT(opendir_req.ptr == NULL); + ASSERT_NULL(opendir_req.ptr); uv_fs_req_cleanup(&opendir_req); @@ -329,7 +329,7 @@ static void non_empty_opendir_cb(uv_fs_t* req) { ASSERT(req == &opendir_req); ASSERT(req->fs_type == UV_FS_OPENDIR); ASSERT(req->result == 0); - ASSERT(req->ptr != NULL); + ASSERT_NOT_NULL(req->ptr); dir = req->ptr; dir->dirents = dirents; @@ -403,7 +403,7 @@ TEST_IMPL(fs_readdir_non_empty_dir) { ASSERT(r == 0); ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); ASSERT(opendir_req.result == 0); - ASSERT(opendir_req.ptr != NULL); + ASSERT_NOT_NULL(opendir_req.ptr); entries_count = 0; dir = opendir_req.ptr; diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 0292a96b4802ca..034c971d3620e8 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -343,7 +343,7 @@ static void statfs_cb(uv_fs_t* req) { ASSERT(req->fs_type == UV_FS_STATFS); ASSERT(req->result == 0); - ASSERT(req->ptr != NULL); + ASSERT_NOT_NULL(req->ptr); stats = req->ptr; #if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \ @@ -366,7 +366,7 @@ static void statfs_cb(uv_fs_t* req) { ASSERT(stats->f_ffree <= stats->f_files); #endif uv_fs_req_cleanup(req); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); statfs_cb_count++; } @@ -630,7 +630,7 @@ static void empty_scandir_cb(uv_fs_t* req) { ASSERT(req == &scandir_req); ASSERT(req->fs_type == UV_FS_SCANDIR); ASSERT(req->result == 0); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent)); uv_fs_req_cleanup(req); scandir_cb_count++; @@ -642,7 +642,7 @@ static void non_existent_scandir_cb(uv_fs_t* req) { ASSERT(req == &scandir_req); ASSERT(req->fs_type == UV_FS_SCANDIR); ASSERT(req->result == UV_ENOENT); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent)); uv_fs_req_cleanup(req); scandir_cb_count++; @@ -653,7 +653,7 @@ static void file_scandir_cb(uv_fs_t* req) { ASSERT(req == &scandir_req); ASSERT(req->fs_type == UV_FS_SCANDIR); ASSERT(req->result == UV_ENOTDIR); - ASSERT(req->ptr == NULL); + ASSERT_NULL(req->ptr); uv_fs_req_cleanup(req); scandir_cb_count++; } @@ -1453,7 +1453,8 @@ TEST_IMPL(fs_fstat) { ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec); ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec); ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec); -#elif defined(_AIX) +#elif defined(_AIX) || \ + defined(__MVS__) ASSERT(s->st_atim.tv_sec == t.st_atime); ASSERT(s->st_atim.tv_nsec == 0); ASSERT(s->st_mtim.tv_sec == t.st_mtime); @@ -2011,12 +2012,12 @@ TEST_IMPL(fs_readlink) { ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb)); ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); ASSERT(dummy_cb_count == 1); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); ASSERT(req.result == UV_ENOENT); uv_fs_req_cleanup(&req); ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL)); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); ASSERT(req.result == UV_ENOENT); uv_fs_req_cleanup(&req); @@ -2032,7 +2033,7 @@ TEST_IMPL(fs_realpath) { ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb)); ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); ASSERT(dummy_cb_count == 1); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); #ifdef _WIN32 /* * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() @@ -2046,7 +2047,7 @@ TEST_IMPL(fs_realpath) { uv_fs_req_cleanup(&req); ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL)); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); ASSERT(req.result == UV_ENOENT); uv_fs_req_cleanup(&req); @@ -2843,7 +2844,7 @@ TEST_IMPL(fs_scandir_empty_dir) { r = uv_fs_scandir(NULL, &req, path, 0, NULL); ASSERT(r == 0); ASSERT(req.result == 0); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent)); uv_fs_req_cleanup(&req); @@ -2880,7 +2881,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) { r = uv_fs_scandir(NULL, &req, path, 0, NULL); ASSERT(r == UV_ENOENT); ASSERT(req.result == UV_ENOENT); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent)); uv_fs_req_cleanup(&req); @@ -2932,7 +2933,7 @@ TEST_IMPL(fs_open_dir) { r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL); ASSERT(r >= 0); ASSERT(req.result >= 0); - ASSERT(req.ptr == NULL); + ASSERT_NULL(req.ptr); file = r; uv_fs_req_cleanup(&req); @@ -3332,7 +3333,7 @@ static void fs_write_alotof_bufs(int add_flags) { loop = uv_default_loop(); iovs = malloc(sizeof(*iovs) * iovcount); - ASSERT(iovs != NULL); + ASSERT_NOT_NULL(iovs); iovmax = uv_test_getiovmax(); r = uv_fs_open(NULL, @@ -3361,7 +3362,7 @@ static void fs_write_alotof_bufs(int add_flags) { /* Read the strings back to separate buffers. */ buffer = malloc(sizeof(test_buf) * iovcount); - ASSERT(buffer != NULL); + ASSERT_NOT_NULL(buffer); for (index = 0; index < iovcount; ++index) iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), @@ -3444,7 +3445,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) { loop = uv_default_loop(); iovs = malloc(sizeof(*iovs) * iovcount); - ASSERT(iovs != NULL); + ASSERT_NOT_NULL(iovs); iovmax = uv_test_getiovmax(); r = uv_fs_open(NULL, @@ -3480,7 +3481,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) { /* Read the strings back to separate buffers. */ buffer = malloc(sizeof(test_buf) * iovcount); - ASSERT(buffer != NULL); + ASSERT_NOT_NULL(buffer); for (index = 0; index < iovcount; ++index) iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), @@ -3676,16 +3677,16 @@ static void test_fs_partial(int doread) { iovcount = 54321; iovs = malloc(sizeof(*iovs) * iovcount); - ASSERT(iovs != NULL); + ASSERT_NOT_NULL(iovs); ctx.pid = pthread_self(); ctx.doread = doread; ctx.interval = 1000; ctx.size = sizeof(test_buf) * iovcount; ctx.data = malloc(ctx.size); - ASSERT(ctx.data != NULL); + ASSERT_NOT_NULL(ctx.data); buffer = malloc(ctx.size); - ASSERT(buffer != NULL); + ASSERT_NOT_NULL(buffer); for (index = 0; index < iovcount; ++index) iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), sizeof(test_buf)); @@ -3773,15 +3774,15 @@ TEST_IMPL(fs_read_write_null_arguments) { /* Validate some memory management on failed input validation before sending fs work to the thread pool. */ ASSERT(r == UV_EINVAL); - ASSERT(write_req.path == NULL); - ASSERT(write_req.ptr == NULL); + ASSERT_NULL(write_req.path); + ASSERT_NULL(write_req.ptr); #ifdef _WIN32 - ASSERT(write_req.file.pathw == NULL); - ASSERT(write_req.fs.info.new_pathw == NULL); - ASSERT(write_req.fs.info.bufs == NULL); + ASSERT_NULL(write_req.file.pathw); + ASSERT_NULL(write_req.fs.info.new_pathw); + ASSERT_NULL(write_req.fs.info.bufs); #else - ASSERT(write_req.new_path == NULL); - ASSERT(write_req.bufs == NULL); + ASSERT_NULL(write_req.new_path); + ASSERT_NULL(write_req.bufs); #endif uv_fs_req_cleanup(&write_req); diff --git a/deps/uv/test/test-get-currentexe.c b/deps/uv/test/test-get-currentexe.c index 8eba7b73b7b036..dc239cc89d1435 100644 --- a/deps/uv/test/test-get-currentexe.c +++ b/deps/uv/test/test-get-currentexe.c @@ -49,7 +49,7 @@ TEST_IMPL(get_currentexe) { #ifdef _WIN32 snprintf(path, sizeof(path), "%s", executable_path); #else - ASSERT(NULL != realpath(executable_path, path)); + ASSERT_NOT_NULL(realpath(executable_path, path)); #endif match = strstr(buffer, path); diff --git a/deps/uv/test/test-get-passwd.c b/deps/uv/test/test-get-passwd.c index abe8be36a332b5..865c07d651507a 100644 --- a/deps/uv/test/test-get-passwd.c +++ b/deps/uv/test/test-get-passwd.c @@ -40,7 +40,7 @@ TEST_IMPL(get_passwd) { ASSERT(len > 0); #ifdef _WIN32 - ASSERT(pwd.shell == NULL); + ASSERT_NULL(pwd.shell); #else len = strlen(pwd.shell); # ifndef __PASE__ @@ -74,16 +74,16 @@ TEST_IMPL(get_passwd) { /* Test uv_os_free_passwd() */ uv_os_free_passwd(&pwd); - ASSERT(pwd.username == NULL); - ASSERT(pwd.shell == NULL); - ASSERT(pwd.homedir == NULL); + ASSERT_NULL(pwd.username); + ASSERT_NULL(pwd.shell); + ASSERT_NULL(pwd.homedir); /* Test a double free */ uv_os_free_passwd(&pwd); - ASSERT(pwd.username == NULL); - ASSERT(pwd.shell == NULL); - ASSERT(pwd.homedir == NULL); + ASSERT_NULL(pwd.username); + ASSERT_NULL(pwd.shell); + ASSERT_NULL(pwd.homedir); /* Test invalid input */ r = uv_os_get_passwd(NULL); diff --git a/deps/uv/test/test-getaddrinfo.c b/deps/uv/test/test-getaddrinfo.c index b1fc312349f960..d0b6a505016dd8 100644 --- a/deps/uv/test/test-getaddrinfo.c +++ b/deps/uv/test/test-getaddrinfo.c @@ -42,7 +42,7 @@ static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req, ASSERT(fail_cb_called == 0); ASSERT(status < 0); - ASSERT(res == NULL); + ASSERT_NULL(res); uv_freeaddrinfo(res); /* Should not crash. */ fail_cb_called++; } @@ -191,7 +191,7 @@ TEST_IMPL(getaddrinfo_concurrent) { callback_counts[i] = 0; data = (int*)malloc(sizeof(int)); - ASSERT(data != NULL); + ASSERT_NOT_NULL(data); *data = i; getaddrinfo_handles[i].data = data; diff --git a/deps/uv/test/test-getnameinfo.c b/deps/uv/test/test-getnameinfo.c index eb3264515ce509..2bfedd3a39b233 100644 --- a/deps/uv/test/test-getnameinfo.c +++ b/deps/uv/test/test-getnameinfo.c @@ -38,10 +38,10 @@ static void getnameinfo_req(uv_getnameinfo_t* handle, int status, const char* hostname, const char* service) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); ASSERT(status == 0); - ASSERT(hostname != NULL); - ASSERT(service != NULL); + ASSERT_NOT_NULL(hostname); + ASSERT_NOT_NULL(service); } diff --git a/deps/uv/test/test-getsockname.c b/deps/uv/test/test-getsockname.c index 565c17fe50b552..7c77fcb0a9b605 100644 --- a/deps/uv/test/test-getsockname.c +++ b/deps/uv/test/test-getsockname.c @@ -116,7 +116,7 @@ static void on_connection(uv_stream_t* server, int status) { ASSERT(status == 0); handle = malloc(sizeof(*handle)); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); r = uv_tcp_init(loop, handle); ASSERT(r == 0); diff --git a/deps/uv/test/test-getters-setters.c b/deps/uv/test/test-getters-setters.c index 42c9dcaf0cb2c7..2a37122df3f6aa 100644 --- a/deps/uv/test/test-getters-setters.c +++ b/deps/uv/test/test-getters-setters.c @@ -33,9 +33,9 @@ TEST_IMPL(handle_type_name) { ASSERT(strcmp(uv_handle_type_name(UV_NAMED_PIPE), "pipe") == 0); ASSERT(strcmp(uv_handle_type_name(UV_UDP), "udp") == 0); ASSERT(strcmp(uv_handle_type_name(UV_FILE), "file") == 0); - ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX) == NULL); - ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1) == NULL); - ASSERT(uv_handle_type_name(UV_UNKNOWN_HANDLE) == NULL); + ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX)); + ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1)); + ASSERT_NULL(uv_handle_type_name(UV_UNKNOWN_HANDLE)); return 0; } @@ -44,9 +44,9 @@ TEST_IMPL(req_type_name) { ASSERT(strcmp(uv_req_type_name(UV_REQ), "req") == 0); ASSERT(strcmp(uv_req_type_name(UV_UDP_SEND), "udp_send") == 0); ASSERT(strcmp(uv_req_type_name(UV_WORK), "work") == 0); - ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX) == NULL); - ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX + 1) == NULL); - ASSERT(uv_req_type_name(UV_UNKNOWN_REQ) == NULL); + ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX)); + ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX + 1)); + ASSERT_NULL(uv_req_type_name(UV_UNKNOWN_REQ)); return 0; } @@ -58,7 +58,7 @@ TEST_IMPL(getters_setters) { int r; loop = malloc(uv_loop_size()); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); r = uv_loop_init(loop); ASSERT(r == 0); diff --git a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c index 753fb7b7c209e7..89b977d2c34080 100644 --- a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c +++ b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c @@ -66,7 +66,7 @@ static void do_write(uv_stream_t* handle) { int r; write_info = malloc(sizeof *write_info); - ASSERT(write_info != NULL); + ASSERT_NOT_NULL(write_info); for (i = 0; i < BUFFERS_PER_WRITE; i++) { memset(&write_info->buffers[i], BUFFER_CONTENT, BUFFER_SIZE); diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index ba3ba737481532..68a0e1bb8144ca 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -203,7 +203,7 @@ static void on_read(uv_stream_t* handle, /* Make sure that the expected data is correctly multiplexed. */ ASSERT_MEM_EQ("hello\n", buf->base, nread); - outbuf = uv_buf_init("world\n", 6); + outbuf = uv_buf_init("foobar\n", 7); r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL); ASSERT_EQ(r, 0); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 74588407cfbd8d..59b95da9ebe346 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -206,6 +206,7 @@ TEST_DECLARE (connection_fail_doesnt_auto_close) TEST_DECLARE (shutdown_close_tcp) TEST_DECLARE (shutdown_close_pipe) TEST_DECLARE (shutdown_eof) +TEST_DECLARE (shutdown_simultaneous) TEST_DECLARE (shutdown_twice) TEST_DECLARE (callback_stack) TEST_DECLARE (env_vars) @@ -504,6 +505,10 @@ TEST_DECLARE (handle_type_name) TEST_DECLARE (req_type_name) TEST_DECLARE (getters_setters) +TEST_DECLARE (not_writable_after_shutdown) +TEST_DECLARE (not_readable_nor_writable_on_read_error) +TEST_DECLARE (not_readable_on_eof) + #ifndef _WIN32 TEST_DECLARE (fork_timer) TEST_DECLARE (fork_socketpair) @@ -780,6 +785,9 @@ TASK_LIST_START TEST_ENTRY (shutdown_eof) TEST_HELPER (shutdown_eof, tcp4_echo_server) + TEST_ENTRY (shutdown_simultaneous) + TEST_HELPER (shutdown_simultaneous, tcp4_echo_server) + TEST_ENTRY (shutdown_twice) TEST_HELPER (shutdown_twice, tcp4_echo_server) @@ -1129,6 +1137,13 @@ TASK_LIST_START TEST_ENTRY (idna_toascii) #endif + TEST_ENTRY (not_writable_after_shutdown) + TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server) + TEST_ENTRY (not_readable_nor_writable_on_read_error) + TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server) + TEST_ENTRY (not_readable_on_eof) + TEST_HELPER (not_readable_on_eof, tcp4_echo_server) + TEST_ENTRY (metrics_idle_time) TEST_ENTRY (metrics_idle_time_thread) TEST_ENTRY (metrics_idle_time_zero) diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c index 131098801ae126..05cb8466ca626e 100644 --- a/deps/uv/test/test-loop-handles.c +++ b/deps/uv/test/test-loop-handles.c @@ -143,7 +143,7 @@ static void idle_1_cb(uv_idle_t* handle) { fprintf(stderr, "%s", "IDLE_1_CB\n"); fflush(stderr); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); ASSERT(idles_1_active > 0); /* Init idle_2 and make it active */ @@ -170,7 +170,7 @@ static void idle_1_close_cb(uv_handle_t* handle) { fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n"); fflush(stderr); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); idle_1_close_cb_called++; } diff --git a/deps/uv/test/test-multiple-listen.c b/deps/uv/test/test-multiple-listen.c index 4ae5fa67b3a342..0b2851411a862b 100644 --- a/deps/uv/test/test-multiple-listen.c +++ b/deps/uv/test/test-multiple-listen.c @@ -32,7 +32,7 @@ static uv_tcp_t client; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -65,7 +65,7 @@ static void start_server(void) { static void connect_cb(uv_connect_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); free(req); uv_close((uv_handle_t*)&client, close_cb); @@ -79,7 +79,7 @@ static void client_connect(void) { int r; ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(connect_req != NULL); + ASSERT_NOT_NULL(connect_req); r = uv_tcp_init(uv_default_loop(), &client); ASSERT(r == 0); diff --git a/deps/uv/test/test-not-readable-nor-writable-on-read-error.c b/deps/uv/test/test-not-readable-nor-writable-on-read-error.c new file mode 100644 index 00000000000000..ae951e39893b36 --- /dev/null +++ b/deps/uv/test/test-not-readable-nor-writable-on-read-error.c @@ -0,0 +1,104 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_loop_t loop; +static uv_tcp_t tcp_client; +static uv_connect_t connect_req; +static uv_write_t write_req; +static char reset_me_cmd[] = {'Q', 'S', 'H'}; + +static int connect_cb_called; +static int read_cb_called; +static int write_cb_called; +static int close_cb_called; + +static void write_cb(uv_write_t* req, int status) { + write_cb_called++; + ASSERT(status == 0); +} + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[64]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + read_cb_called++; + + ASSERT((nread < 0) && (nread != UV_EOF)); + ASSERT(0 == uv_is_writable(handle)); + ASSERT(0 == uv_is_readable(handle)); + + uv_close((uv_handle_t*) handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t reset_me; + + connect_cb_called++; + ASSERT(status == 0); + + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT(r == 0); + + reset_me = uv_buf_init(reset_me_cmd, sizeof(reset_me_cmd)); + + r = uv_write(&write_req, + (uv_stream_t*) &tcp_client, + &reset_me, + 1, + write_cb); + + ASSERT(r == 0); +} + +TEST_IMPL(not_readable_nor_writable_on_read_error) { + struct sockaddr_in sa; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); + + ASSERT(0 == uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb)); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(read_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-not-readable-on-eof.c b/deps/uv/test/test-not-readable-on-eof.c new file mode 100644 index 00000000000000..2bb5f4eecccf76 --- /dev/null +++ b/deps/uv/test/test-not-readable-on-eof.c @@ -0,0 +1,103 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_loop_t loop; +static uv_tcp_t tcp_client; +static uv_connect_t connect_req; +static uv_write_t write_req; +static char close_me_cmd[] = {'Q', 'S'}; + +static int connect_cb_called; +static int read_cb_called; +static int write_cb_called; +static int close_cb_called; + +static void write_cb(uv_write_t* req, int status) { + write_cb_called++; + ASSERT(status == 0); +} + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[64]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + read_cb_called++; + + ASSERT(nread == UV_EOF); + ASSERT(0 == uv_is_readable(handle)); + + uv_close((uv_handle_t*) handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t close_me; + + connect_cb_called++; + ASSERT(status == 0); + + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT(r == 0); + + close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd)); + + r = uv_write(&write_req, + (uv_stream_t*) &tcp_client, + &close_me, + 1, + write_cb); + + ASSERT(r == 0); +} + +TEST_IMPL(not_readable_on_eof) { + struct sockaddr_in sa; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); + + ASSERT(0 == uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb)); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(read_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-not-writable-after-shutdown.c b/deps/uv/test/test-not-writable-after-shutdown.c new file mode 100644 index 00000000000000..9cd93703cea292 --- /dev/null +++ b/deps/uv/test/test-not-writable-after-shutdown.c @@ -0,0 +1,69 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_shutdown_t shutdown_req; + +static void close_cb(uv_handle_t* handle) { + +} + +static void shutdown_cb(uv_shutdown_t* req, int status) { + uv_close((uv_handle_t*) req->handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + ASSERT(status == 0); + + r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_is_writable(req->handle)); +} + +TEST_IMPL(not_writable_after_shutdown) { + int r; + struct sockaddr_in addr; + uv_loop_t* loop; + uv_tcp_t socket; + uv_connect_t connect_req; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + r = uv_tcp_init(loop, &socket); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &socket, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c index 9cf93165e41301..ce35052f537fdc 100644 --- a/deps/uv/test/test-pipe-bind-error.c +++ b/deps/uv/test/test-pipe-bind-error.c @@ -36,7 +36,7 @@ static int close_cb_called = 0; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c index 8bba328a344f17..30c270d9fce8f4 100644 --- a/deps/uv/test/test-pipe-connect-error.c +++ b/deps/uv/test/test-pipe-connect-error.c @@ -37,7 +37,7 @@ static int connect_cb_called = 0; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-pipe-connect-prepare.c b/deps/uv/test/test-pipe-connect-prepare.c index a86e7284a799fd..08b57cbf51094c 100644 --- a/deps/uv/test/test-pipe-connect-prepare.c +++ b/deps/uv/test/test-pipe-connect-prepare.c @@ -42,7 +42,7 @@ static uv_connect_t conn_req; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c index 5f377dcbb60696..79db8eba7177e0 100644 --- a/deps/uv/test/test-pipe-getsockname.c +++ b/deps/uv/test/test-pipe-getsockname.c @@ -96,7 +96,7 @@ TEST_IMPL(pipe_getsockname) { int r; loop = uv_default_loop(); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); r = uv_pipe_init(loop, &pipe_server, 0); ASSERT(r == 0); diff --git a/deps/uv/test/test-pipe-server-close.c b/deps/uv/test/test-pipe-server-close.c index ea9977dd843e2a..25305b397b2e05 100644 --- a/deps/uv/test/test-pipe-server-close.c +++ b/deps/uv/test/test-pipe-server-close.c @@ -68,7 +68,7 @@ TEST_IMPL(pipe_server_close) { int r; loop = uv_default_loop(); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); r = uv_pipe_init(loop, &pipe_server, 0); ASSERT(r == 0); diff --git a/deps/uv/test/test-pipe-set-non-blocking.c b/deps/uv/test/test-pipe-set-non-blocking.c index c45148f2bd028d..8246afaf827003 100644 --- a/deps/uv/test/test-pipe-set-non-blocking.c +++ b/deps/uv/test/test-pipe-set-non-blocking.c @@ -105,10 +105,10 @@ TEST_IMPL(pipe_set_non_blocking) { #ifdef _WIN32 ASSERT(n == UV_EAGAIN); /* E_NOTIMPL */ ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &pipe_handle, &buf, 1, write_cb)); - ASSERT(write_req.handle != NULL); + ASSERT_NOT_NULL(write_req.handle); ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* queue write_cb */ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* process write_cb */ - ASSERT(write_req.handle == NULL); /* check for signaled completion of write_cb */ + ASSERT_NULL(write_req.handle); /* check for signaled completion of write_cb */ n = buf.len; #endif ASSERT(n == sizeof(data)); diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c index edd75d38266768..3bc422d2795543 100644 --- a/deps/uv/test/test-poll.c +++ b/deps/uv/test/test-poll.c @@ -147,7 +147,7 @@ static connection_context_t* create_connection_context( connection_context_t* context; context = (connection_context_t*) malloc(sizeof *context); - ASSERT(context != NULL); + ASSERT_NOT_NULL(context); context->sock = sock; context->is_server_connection = is_server_connection; @@ -464,7 +464,7 @@ static server_context_t* create_server_context( server_context_t* context; context = (server_context_t*) malloc(sizeof *context); - ASSERT(context != NULL); + ASSERT_NOT_NULL(context); context->sock = sock; context->connections = 0; diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c index 05728c83365bfe..d24ea4a01e8aba 100644 --- a/deps/uv/test/test-ref.c +++ b/deps/uv/test/test-ref.c @@ -154,7 +154,7 @@ TEST_IMPL(check_ref) { static void prepare_cb(uv_prepare_t* h) { - ASSERT(h != NULL); + ASSERT_NOT_NULL(h); uv_unref((uv_handle_t*)h); } diff --git a/deps/uv/test/test-shutdown-simultaneous.c b/deps/uv/test/test-shutdown-simultaneous.c new file mode 100644 index 00000000000000..7de3bd42252e62 --- /dev/null +++ b/deps/uv/test/test-shutdown-simultaneous.c @@ -0,0 +1,135 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static uv_tcp_t tcp; +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; +static uv_buf_t qbuf; +static int got_q; +static int got_eof; +static int called_connect_cb; +static int called_shutdown_cb; +static int called_tcp_close_cb; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void shutdown_cb(uv_shutdown_t *req, int status) { + ASSERT_PTR_EQ(req, &shutdown_req); + + ASSERT_EQ(called_connect_cb, 1); + ASSERT_EQ(called_tcp_close_cb, 0); +} + + +static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) { + ASSERT_PTR_EQ((uv_tcp_t*)t, &tcp); + + if (nread == 0) { + free(buf->base); + return; + } + + if (!got_q) { + ASSERT_EQ(nread, 4); + ASSERT_EQ(got_eof, 0); + ASSERT_MEM_EQ(buf->base, "QQSS", 4); + free(buf->base); + got_q = 1; + puts("got QQSS"); + /* Shutdown our end of the connection simultaneously */ + uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb); + called_shutdown_cb++; + } else { + ASSERT_EQ(nread, UV_EOF); + if (buf->base) { + free(buf->base); + } + got_eof = 1; + puts("got EOF"); + } +} + + +static void connect_cb(uv_connect_t *req, int status) { + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(req, &connect_req); + + /* Start reading from our connection so we can receive the EOF. */ + ASSERT_EQ(0, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + + /* Check error handling. */ + ASSERT_EQ(UV_EALREADY, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start(NULL, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, NULL, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, alloc_cb, NULL)); + + /* + * Write the letter 'Q' and 'QSS` to gracefully kill the echo-server. This + * will not effect our connection. + */ + ASSERT_EQ(qbuf.len, uv_try_write((uv_stream_t*) &tcp, &qbuf, 1)); + + called_connect_cb++; + ASSERT_EQ(called_shutdown_cb, 0); +} + + +/* + * This test has a client which connects to the echo_server and immediately + * issues a shutdown. We check that this does not cause libuv to hang. + */ +TEST_IMPL(shutdown_simultaneous) { + struct sockaddr_in server_addr; + int r; + + qbuf.base = "QQSS"; + qbuf.len = 4; + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT_EQ(r, 0); + + r = uv_tcp_connect(&connect_req, + &tcp, + (const struct sockaddr*) &server_addr, + connect_cb); + ASSERT_EQ(r, 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(called_connect_cb, 1); + ASSERT_EQ(called_shutdown_cb, 1); + ASSERT_EQ(got_eof, 1); + ASSERT_EQ(got_q, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c index 09d9cacb3af6b4..7d61ff61e0d9e9 100644 --- a/deps/uv/test/test-signal-multiple-loops.c +++ b/deps/uv/test/test-signal-multiple-loops.c @@ -170,7 +170,7 @@ static void loop_creating_worker(void* context) { int r; loop = malloc(sizeof(*loop)); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); ASSERT(0 == uv_loop_init(loop)); r = uv_signal_init(loop, &signal); diff --git a/deps/uv/test/test-signal-pending-on-close.c b/deps/uv/test/test-signal-pending-on-close.c index 23b9ec8d16f1d4..428a97ef5ae30d 100644 --- a/deps/uv/test/test-signal-pending-on-close.c +++ b/deps/uv/test/test-signal-pending-on-close.c @@ -49,7 +49,7 @@ static void close_cb(uv_handle_t *handle) { static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == UV_EPIPE); free(buf); uv_close((uv_handle_t *) &pipe_hdl, close_cb); @@ -76,7 +76,7 @@ TEST_IMPL(signal_pending_on_close) { /* Write data large enough so it needs loop iteration */ buf = malloc(1<<24); - ASSERT(buf != NULL); + ASSERT_NOT_NULL(buf); memset(buf, '.', 1<<24); buffer = uv_buf_init(buf, 1<<24); diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 886ddaf63b509d..9f2eb24b2d6daf 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -1176,7 +1176,7 @@ TEST_IMPL(argument_escaping) { WCHAR* non_verbatim_output; test_output = calloc(count, sizeof(WCHAR*)); - ASSERT(test_output != NULL); + ASSERT_NOT_NULL(test_output); for (i = 0; i < count; ++i) { test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR)); quote_cmd_arg(test_str[i], test_output[i]); @@ -1185,7 +1185,7 @@ TEST_IMPL(argument_escaping) { total_size += wcslen(test_output[i]) + 1; } command_line = calloc(total_size + 1, sizeof(WCHAR)); - ASSERT(command_line != NULL); + ASSERT_NOT_NULL(command_line); for (i = 0; i < count; ++i) { wcscat(command_line, test_output[i]); wcscat(command_line, L" "); @@ -1351,7 +1351,7 @@ TEST_IMPL(spawn_with_an_odd_path) { char newpath[2048]; char *path = getenv("PATH"); - ASSERT(path != NULL); + ASSERT_NOT_NULL(path); snprintf(newpath, 2048, ";.;%s", path); SetEnvironmentVariable("PATH", newpath); @@ -1385,7 +1385,7 @@ TEST_IMPL(spawn_setuid_setgid) { /* become the "nobody" user. */ pw = getpwnam("nobody"); - ASSERT(pw != NULL); + ASSERT_NOT_NULL(pw); options.uid = pw->pw_uid; options.gid = pw->pw_gid; snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid); @@ -1423,7 +1423,7 @@ TEST_IMPL(spawn_setuid_fails) { if (uid == 0) { struct passwd* pw; pw = getpwnam("nobody"); - ASSERT(pw != NULL); + ASSERT_NOT_NULL(pw); ASSERT(0 == setgid(pw->pw_gid)); ASSERT(0 == setuid(pw->pw_uid)); } @@ -1474,7 +1474,7 @@ TEST_IMPL(spawn_setgid_fails) { if (uid == 0) { struct passwd* pw; pw = getpwnam("nobody"); - ASSERT(pw != NULL); + ASSERT_NOT_NULL(pw); ASSERT(0 == setgid(pw->pw_gid)); ASSERT(0 == setuid(pw->pw_uid)); } diff --git a/deps/uv/test/test-tcp-alloc-cb-fail.c b/deps/uv/test/test-tcp-alloc-cb-fail.c index 61ca667acbcab3..b6f4ca38850bac 100644 --- a/deps/uv/test/test-tcp-alloc-cb-fail.c +++ b/deps/uv/test/test-tcp-alloc-cb-fail.c @@ -53,7 +53,7 @@ static void conn_read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { ASSERT(nread == UV_ENOBUFS); - ASSERT(buf->base == NULL); + ASSERT_NULL(buf->base); ASSERT(buf->len == 0); uv_close((uv_handle_t*) &incoming, close_cb); diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c index 7732267f44f54e..fdd1fe07450d73 100644 --- a/deps/uv/test/test-tcp-bind-error.c +++ b/deps/uv/test/test-tcp-bind-error.c @@ -30,7 +30,7 @@ static int close_cb_called = 0; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-tcp-bind6-error.c b/deps/uv/test/test-tcp-bind6-error.c index b762bcb3d1b8d0..86181b708e3fd2 100644 --- a/deps/uv/test/test-tcp-bind6-error.c +++ b/deps/uv/test/test-tcp-bind6-error.c @@ -29,7 +29,7 @@ static int close_cb_called = 0; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-tcp-close.c b/deps/uv/test/test-tcp-close.c index e65885aa5563a7..5a7bd6893bf479 100644 --- a/deps/uv/test/test-tcp-close.c +++ b/deps/uv/test/test-tcp-close.c @@ -46,7 +46,7 @@ static void connect_cb(uv_connect_t* conn_req, int status) { buf = uv_buf_init("PING", 4); for (i = 0; i < NUM_WRITE_REQS; i++) { req = malloc(sizeof *req); - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); r = uv_write(req, (uv_stream_t*)&tcp_handle, &buf, 1, write_cb); ASSERT(r == 0); diff --git a/deps/uv/test/test-tcp-connect-error.c b/deps/uv/test/test-tcp-connect-error.c index eab1eeb25457bb..dda30a58064f8f 100644 --- a/deps/uv/test/test-tcp-connect-error.c +++ b/deps/uv/test/test-tcp-connect-error.c @@ -31,14 +31,14 @@ static int close_cb_called = 0; static void connect_cb(uv_connect_t* handle, int status) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); connect_cb_called++; } static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-tcp-connect6-error.c b/deps/uv/test/test-tcp-connect6-error.c index 91ac0a3a101f86..2f6e9cbce14336 100644 --- a/deps/uv/test/test-tcp-connect6-error.c +++ b/deps/uv/test/test-tcp-connect6-error.c @@ -30,13 +30,13 @@ static int close_cb_called = 0; static void connect_cb(uv_connect_t* handle, int status) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); connect_cb_called++; } static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-tcp-create-socket-early.c b/deps/uv/test/test-tcp-create-socket-early.c index b87e7324184be1..f2bc60d7c7c0ec 100644 --- a/deps/uv/test/test-tcp-create-socket-early.c +++ b/deps/uv/test/test-tcp-create-socket-early.c @@ -44,7 +44,7 @@ static void on_connection(uv_stream_t* server, int status) { ASSERT(status == 0); handle = malloc(sizeof(*handle)); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); r = uv_tcp_init_ex(server->loop, handle, AF_INET); ASSERT(r == 0); diff --git a/deps/uv/test/test-tcp-open.c b/deps/uv/test/test-tcp-open.c index 0d92886d61f225..7e49139cd81a86 100644 --- a/deps/uv/test/test-tcp-open.c +++ b/deps/uv/test/test-tcp-open.c @@ -96,7 +96,7 @@ static void alloc_cb(uv_handle_t* handle, static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -111,7 +111,7 @@ static void shutdown_cb(uv_shutdown_t* req, int status) { static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(tcp != NULL); + ASSERT_NOT_NULL(tcp); if (nread >= 0) { ASSERT(nread == 4); @@ -126,7 +126,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { int i; - ASSERT(tcp != NULL); + ASSERT_NOT_NULL(tcp); if (nread >= 0) { for (i = 0; i < nread; ++i) @@ -140,7 +140,7 @@ static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); if (status) { fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); @@ -155,7 +155,7 @@ static void write1_cb(uv_write_t* req, int status) { uv_buf_t buf; int r; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); if (status) { ASSERT(shutdown_cb_called); return; @@ -237,6 +237,7 @@ TEST_IMPL(tcp_open) { struct sockaddr_in addr; uv_os_sock_t sock; int r; + uv_tcp_t client2; ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); @@ -257,8 +258,6 @@ TEST_IMPL(tcp_open) { #ifndef _WIN32 { - uv_tcp_t client2; - r = uv_tcp_init(uv_default_loop(), &client2); ASSERT(r == 0); @@ -267,7 +266,9 @@ TEST_IMPL(tcp_open) { uv_close((uv_handle_t*) &client2, NULL); } -#endif /* !_WIN32 */ +#else /* _WIN32 */ + (void)client2; +#endif uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/deps/uv/test/test-tcp-write-fail.c b/deps/uv/test/test-tcp-write-fail.c index 5256a9f4a790aa..58ee00faedb410 100644 --- a/deps/uv/test/test-tcp-write-fail.c +++ b/deps/uv/test/test-tcp-write-fail.c @@ -52,13 +52,13 @@ static void close_socket(uv_tcp_t* sock) { static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status != 0); fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); diff --git a/deps/uv/test/test-tcp-write-to-half-open-connection.c b/deps/uv/test/test-tcp-write-to-half-open-connection.c index 2fa2ae72253fb6..ae4251317d80e6 100644 --- a/deps/uv/test/test-tcp-write-to-half-open-connection.c +++ b/deps/uv/test/test-tcp-write-to-half-open-connection.c @@ -110,7 +110,7 @@ TEST_IMPL(tcp_write_to_half_open_connection) { ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); loop = uv_default_loop(); - ASSERT(loop != NULL); + ASSERT_NOT_NULL(loop); r = uv_tcp_init(loop, &tcp_server); ASSERT(r == 0); diff --git a/deps/uv/test/test-tcp-writealot.c b/deps/uv/test/test-tcp-writealot.c index 7206fdc2f60eb5..40dce96e8d8c34 100644 --- a/deps/uv/test/test-tcp-writealot.c +++ b/deps/uv/test/test-tcp-writealot.c @@ -57,7 +57,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -82,7 +82,7 @@ static void shutdown_cb(uv_shutdown_t* req, int status) { static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { - ASSERT(tcp != NULL); + ASSERT_NOT_NULL(tcp); if (nread >= 0) { bytes_received_done += nread; @@ -98,7 +98,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { static void write_cb(uv_write_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); if (status) { fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); @@ -152,7 +152,7 @@ TEST_IMPL(tcp_writealot) { ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); send_buffer = calloc(1, TOTAL_BYTES); - ASSERT(send_buffer != NULL); + ASSERT_NOT_NULL(send_buffer); r = uv_tcp_init(uv_default_loop(), &client); ASSERT(r == 0); diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c index 432c243999fb15..8de5a6f03a3029 100644 --- a/deps/uv/test/test-thread.c +++ b/deps/uv/test/test-thread.c @@ -194,11 +194,11 @@ TEST_IMPL(threadpool_multiple_event_loops) { static void tls_thread(void* arg) { - ASSERT(NULL == uv_key_get(&tls_key)); + ASSERT_NULL(uv_key_get(&tls_key)); uv_key_set(&tls_key, arg); ASSERT(arg == uv_key_get(&tls_key)); uv_key_set(&tls_key, NULL); - ASSERT(NULL == uv_key_get(&tls_key)); + ASSERT_NULL(uv_key_get(&tls_key)); } @@ -206,7 +206,7 @@ TEST_IMPL(thread_local_storage) { char name[] = "main"; uv_thread_t threads[2]; ASSERT(0 == uv_key_create(&tls_key)); - ASSERT(NULL == uv_key_get(&tls_key)); + ASSERT_NULL(uv_key_get(&tls_key)); uv_key_set(&tls_key, name); ASSERT(name == uv_key_get(&tls_key)); ASSERT(0 == uv_thread_create(threads + 0, tls_thread, threads + 0)); diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c index be252c6f723451..1e867c51cf9c3f 100644 --- a/deps/uv/test/test-threadpool-cancel.c +++ b/deps/uv/test/test-threadpool-cancel.c @@ -98,7 +98,7 @@ static void getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { ASSERT(status == UV_EAI_CANCELED); - ASSERT(res == NULL); + ASSERT_NULL(res); uv_freeaddrinfo(res); /* Should not crash. */ } @@ -108,8 +108,8 @@ static void getnameinfo_cb(uv_getnameinfo_t* handle, const char* hostname, const char* service) { ASSERT(status == UV_EAI_CANCELED); - ASSERT(hostname == NULL); - ASSERT(service == NULL); + ASSERT_NULL(hostname); + ASSERT_NULL(service); } diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c index e87d2edf18f121..834b59d718c8aa 100644 --- a/deps/uv/test/test-timer-again.c +++ b/deps/uv/test/test-timer-again.c @@ -35,7 +35,7 @@ static uint64_t start_time; static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c index ee8331c2045ff3..d0921a967304f1 100644 --- a/deps/uv/test/test-timer.c +++ b/deps/uv/test/test-timer.c @@ -37,7 +37,7 @@ static uv_timer_t huge_timer2; static void once_close_cb(uv_handle_t* handle) { printf("ONCE_CLOSE_CB\n"); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); ASSERT(0 == uv_is_active(handle)); once_close_cb_called++; @@ -47,7 +47,7 @@ static void once_close_cb(uv_handle_t* handle) { static void once_cb(uv_timer_t* handle) { printf("ONCE_CB %d\n", once_cb_called); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); ASSERT(0 == uv_is_active((uv_handle_t*) handle)); once_cb_called++; @@ -62,7 +62,7 @@ static void once_cb(uv_timer_t* handle) { static void repeat_close_cb(uv_handle_t* handle) { printf("REPEAT_CLOSE_CB\n"); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); repeat_close_cb_called++; } @@ -71,7 +71,7 @@ static void repeat_close_cb(uv_handle_t* handle) { static void repeat_cb(uv_timer_t* handle) { printf("REPEAT_CB\n"); - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); ASSERT(1 == uv_is_active((uv_handle_t*) handle)); repeat_cb_called++; diff --git a/deps/uv/test/test-tty-duplicate-key.c b/deps/uv/test/test-tty-duplicate-key.c index 1ec2f3695d99a4..efd79e14786d69 100644 --- a/deps/uv/test/test-tty-duplicate-key.c +++ b/deps/uv/test/test-tty-duplicate-key.c @@ -55,7 +55,7 @@ static void print_err_msg(const char* expect, ssize_t expect_len, static void tty_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) { buf->base = malloc(size); - ASSERT(buf->base != NULL); + ASSERT_NOT_NULL(buf->base); buf->len = size; } diff --git a/deps/uv/test/test-tty-escape-sequence-processing.c b/deps/uv/test/test-tty-escape-sequence-processing.c index c4461e91e06cf9..ef34e5927c52af 100644 --- a/deps/uv/test/test-tty-escape-sequence-processing.c +++ b/deps/uv/test/test-tty-escape-sequence-processing.c @@ -212,9 +212,9 @@ static void capture_screen(uv_tty_t* tty_out, struct captured_screen* cs) { origin.X = 0; origin.Y = cs->si.csbi.srWindow.Top; cs->text = malloc(cs->si.length * sizeof(*cs->text)); - ASSERT(cs->text != NULL); + ASSERT_NOT_NULL(cs->text); cs->attributes = (WORD*) malloc(cs->si.length * sizeof(*cs->attributes)); - ASSERT(cs->attributes != NULL); + ASSERT_NOT_NULL(cs->attributes); ASSERT(ReadConsoleOutputCharacter( tty_out->handle, cs->text, cs->si.length, origin, &length)); ASSERT((unsigned int) cs->si.length == length); diff --git a/deps/uv/test/test-udp-alloc-cb-fail.c b/deps/uv/test/test-udp-alloc-cb-fail.c index 0cee09c942ef2c..6b0980163a5f9e 100644 --- a/deps/uv/test/test-udp-alloc-cb-fail.c +++ b/deps/uv/test/test-udp-alloc-cb-fail.c @@ -83,7 +83,7 @@ static void cl_recv_cb(uv_udp_t* handle, static void cl_send_cb(uv_udp_send_t* req, int status) { int r; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -95,7 +95,7 @@ static void cl_send_cb(uv_udp_send_t* req, int status) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -121,14 +121,14 @@ static void sv_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } CHECK_HANDLE(handle); ASSERT(flags == 0); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(!memcmp("PING", rcvbuf->base, nread)); @@ -136,7 +136,7 @@ static void sv_recv_cb(uv_udp_t* handle, ASSERT(r == 0); req = malloc(sizeof *req); - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); sndbuf = uv_buf_init("PONG", 4); r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb); diff --git a/deps/uv/test/test-udp-connect.c b/deps/uv/test/test-udp-connect.c index 52856f700d210e..89ca1a84fcd294 100644 --- a/deps/uv/test/test-udp-connect.c +++ b/deps/uv/test/test-udp-connect.c @@ -61,7 +61,7 @@ static void close_cb(uv_handle_t* handle) { static void cl_send_cb(uv_udp_send_t* req, int status) { int r; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); if (++cl_send_cb_called == 1) { @@ -87,7 +87,7 @@ static void sv_recv_cb(uv_udp_t* handle, unsigned flags) { if (nread > 0) { ASSERT(nread == 4); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0); if (++sv_recv_cb_called == 4) { uv_close((uv_handle_t*) &server, close_cb); diff --git a/deps/uv/test/test-udp-mmsg.c b/deps/uv/test/test-udp-mmsg.c index 08628a5046fedc..fb24115107231e 100644 --- a/deps/uv/test/test-udp-mmsg.c +++ b/deps/uv/test/test-udp-mmsg.c @@ -54,7 +54,7 @@ static void alloc_cb(uv_handle_t* handle, /* Actually malloc to exercise free'ing the buffer later */ buf->base = malloc(buffer_size); - ASSERT(buf->base != NULL); + ASSERT_NOT_NULL(buf->base); buf->len = buffer_size; alloc_cb_called++; } @@ -77,13 +77,13 @@ static void recv_cb(uv_udp_t* handle, /* free and return if this is a mmsg free-only callback invocation */ if (flags & UV_UDP_MMSG_FREE) { ASSERT_EQ(nread, 0); - ASSERT(addr == NULL); + ASSERT_NULL(addr); free(rcvbuf->base); return; } ASSERT_EQ(nread, 4); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT_MEM_EQ("PING", rcvbuf->base, nread); recv_cb_called++; diff --git a/deps/uv/test/test-udp-multicast-interface.c b/deps/uv/test/test-udp-multicast-interface.c index 9d36098d0d0ac2..bd9a61c98aa6e2 100644 --- a/deps/uv/test/test-udp-multicast-interface.c +++ b/deps/uv/test/test-udp-multicast-interface.c @@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); CHECK_HANDLE(req->handle); diff --git a/deps/uv/test/test-udp-multicast-interface6.c b/deps/uv/test/test-udp-multicast-interface6.c index 23a68a00f85625..be11514c805900 100644 --- a/deps/uv/test/test-udp-multicast-interface6.c +++ b/deps/uv/test/test-udp-multicast-interface6.c @@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c index cb3ff871eb9111..9e603a8455f736 100644 --- a/deps/uv/test/test-udp-multicast-join.c +++ b/deps/uv/test/test-udp-multicast-join.c @@ -60,7 +60,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -103,11 +103,11 @@ static void cl_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(!memcmp("PING", buf->base, nread)); diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c index 40aa577d0a1b12..e67c5ee59bb1fb 100644 --- a/deps/uv/test/test-udp-multicast-join6.c +++ b/deps/uv/test/test-udp-multicast-join6.c @@ -72,7 +72,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -115,11 +115,11 @@ static void cl_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(!memcmp("PING", buf->base, nread)); diff --git a/deps/uv/test/test-udp-multicast-ttl.c b/deps/uv/test/test-udp-multicast-ttl.c index e92608be4809bf..fbddd90914ca86 100644 --- a/deps/uv/test/test-udp-multicast-ttl.c +++ b/deps/uv/test/test-udp-multicast-ttl.c @@ -43,7 +43,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); CHECK_HANDLE(req->handle); diff --git a/deps/uv/test/test-udp-open.c b/deps/uv/test/test-udp-open.c index dee408baa5c09e..f5136b6d4f281f 100644 --- a/deps/uv/test/test-udp-open.c +++ b/deps/uv/test/test-udp-open.c @@ -91,7 +91,7 @@ static void alloc_cb(uv_handle_t* handle, static void close_cb(uv_handle_t* handle) { - ASSERT(handle != NULL); + ASSERT_NOT_NULL(handle); close_cb_called++; } @@ -109,13 +109,13 @@ static void recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } ASSERT(flags == 0); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(memcmp("PING", buf->base, nread) == 0); @@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle, static void send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); send_cb_called++; @@ -138,7 +138,7 @@ static void send_cb(uv_udp_send_t* req, int status) { TEST_IMPL(udp_open) { struct sockaddr_in addr; uv_buf_t buf = uv_buf_init("PING", 4); - uv_udp_t client; + uv_udp_t client, client2; uv_os_sock_t sock; int r; @@ -169,8 +169,6 @@ TEST_IMPL(udp_open) { #ifndef _WIN32 { - uv_udp_t client2; - r = uv_udp_init(uv_default_loop(), &client2); ASSERT(r == 0); @@ -179,7 +177,9 @@ TEST_IMPL(udp_open) { uv_close((uv_handle_t*) &client2, NULL); } -#endif /* !_WIN32 */ +#else /* _WIN32 */ + (void)client2; +#endif uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/deps/uv/test/test-udp-send-and-recv.c b/deps/uv/test/test-udp-send-and-recv.c index 1f01188b274a49..d60209059b9887 100644 --- a/deps/uv/test/test-udp-send-and-recv.c +++ b/deps/uv/test/test-udp-send-and-recv.c @@ -73,11 +73,11 @@ static void cl_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards cl_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(!memcmp("PONG", buf->base, nread)); @@ -90,7 +90,7 @@ static void cl_recv_cb(uv_udp_t* handle, static void cl_send_cb(uv_udp_send_t* req, int status) { int r; - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -102,7 +102,7 @@ static void cl_send_cb(uv_udp_send_t* req, int status) { static void sv_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -128,14 +128,14 @@ static void sv_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } CHECK_HANDLE(handle); ASSERT(flags == 0); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(!memcmp("PING", rcvbuf->base, nread)); @@ -147,7 +147,7 @@ static void sv_recv_cb(uv_udp_t* handle, ASSERT(r == 0); req = malloc(sizeof *req); - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); sndbuf = uv_buf_init("PONG", 4); r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb); diff --git a/deps/uv/test/test-udp-send-hang-loop.c b/deps/uv/test/test-udp-send-hang-loop.c index bf4dfebfb35098..072070b60e5e65 100644 --- a/deps/uv/test/test-udp-send-hang-loop.c +++ b/deps/uv/test/test-udp-send-hang-loop.c @@ -44,7 +44,7 @@ static void send_cb(uv_udp_send_t* req, int status); static void idle_cb(uv_idle_t* handle) { int r; - ASSERT(send_req.handle == NULL); + ASSERT_NULL(send_req.handle); CHECK_OBJECT(handle, uv_idle_t, idle_handle); ASSERT(0 == uv_idle_stop(handle)); @@ -66,7 +66,7 @@ static void idle_cb(uv_idle_t* handle) { static void send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0 || status == UV_ENETUNREACH); CHECK_OBJECT(req->handle, uv_udp_t, client); CHECK_OBJECT(req, uv_udp_send_t, send_req); diff --git a/deps/uv/test/test-udp-send-immediate.c b/deps/uv/test/test-udp-send-immediate.c index 1011aa467e0541..a1c95d34384ce2 100644 --- a/deps/uv/test/test-udp-send-immediate.c +++ b/deps/uv/test/test-udp-send-immediate.c @@ -56,7 +56,7 @@ static void close_cb(uv_handle_t* handle) { static void cl_send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); CHECK_HANDLE(req->handle); @@ -75,14 +75,14 @@ static void sv_recv_cb(uv_udp_t* handle, if (nread == 0) { /* Returning unused buffer. Don't count towards sv_recv_cb_called */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } CHECK_HANDLE(handle); ASSERT(flags == 0); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(nread == 4); ASSERT(memcmp("PING", rcvbuf->base, nread) == 0 || memcmp("PANG", rcvbuf->base, nread) == 0); diff --git a/deps/uv/test/test-udp-send-unreachable.c b/deps/uv/test/test-udp-send-unreachable.c index c6500320d783b4..c67a23b38529fe 100644 --- a/deps/uv/test/test-udp-send-unreachable.c +++ b/deps/uv/test/test-udp-send-unreachable.c @@ -27,9 +27,10 @@ #include #define CHECK_HANDLE(handle) \ - ASSERT((uv_udp_t*)(handle) == &client) + ASSERT((uv_udp_t*)(handle) == &client || (uv_udp_t*)(handle) == &client2) static uv_udp_t client; +static uv_udp_t client2; static uv_timer_t timer; static int send_cb_called; @@ -37,6 +38,7 @@ static int recv_cb_called; static int close_cb_called; static int alloc_cb_called; static int timer_cb_called; +static int can_recverr; static void alloc_cb(uv_handle_t* handle, @@ -44,7 +46,7 @@ static void alloc_cb(uv_handle_t* handle, uv_buf_t* buf) { static char slab[65536]; CHECK_HANDLE(handle); - ASSERT(suggested_size <= sizeof(slab)); + ASSERT_LE(suggested_size, sizeof(slab)); buf->base = slab; buf->len = sizeof(slab); alloc_cb_called++; @@ -52,18 +54,25 @@ static void alloc_cb(uv_handle_t* handle, static void close_cb(uv_handle_t* handle) { - ASSERT(1 == uv_is_closing(handle)); + ASSERT_EQ(1, uv_is_closing(handle)); close_cb_called++; } static void send_cb(uv_udp_send_t* req, int status) { - ASSERT(req != NULL); + ASSERT_NOT_NULL(req); ASSERT(status == 0); + ASSERT_EQ(status, 0); CHECK_HANDLE(req->handle); send_cb_called++; } +static void send_cb_recverr(uv_udp_send_t* req, int status) { + ASSERT_PTR_NE(req, NULL); + ASSERT(status == 0 || status == UV_ECONNREFUSED); + CHECK_HANDLE(req->handle); + send_cb_called++; +} static void recv_cb(uv_udp_t* handle, ssize_t nread, @@ -77,17 +86,19 @@ static void recv_cb(uv_udp_t* handle, ASSERT(0 && "unexpected error"); } else if (nread == 0) { /* Returning unused buffer */ - ASSERT(addr == NULL); + ASSERT_NULL(addr); } else { - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); } } static void timer_cb(uv_timer_t* h) { - ASSERT(h == &timer); + ASSERT_PTR_EQ(h, &timer); timer_cb_called++; uv_close((uv_handle_t*) &client, close_cb); + if (can_recverr) + uv_close((uv_handle_t*) &client2, close_cb); uv_close((uv_handle_t*) h, close_cb); } @@ -95,27 +106,33 @@ static void timer_cb(uv_timer_t* h) { TEST_IMPL(udp_send_unreachable) { struct sockaddr_in addr; struct sockaddr_in addr2; - uv_udp_send_t req1, req2; + struct sockaddr_in addr3; + uv_udp_send_t req1, req2, req3, req4; uv_buf_t buf; int r; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2)); +#ifdef __linux__ + can_recverr = 1; +#endif + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2)); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_3, &addr3)); r = uv_timer_init( uv_default_loop(), &timer ); - ASSERT(r == 0); + ASSERT_EQ(r, 0); r = uv_timer_start( &timer, timer_cb, 1000, 0 ); - ASSERT(r == 0); + ASSERT_EQ(r, 0); r = uv_udp_init(uv_default_loop(), &client); - ASSERT(r == 0); + ASSERT_EQ(r, 0); r = uv_udp_bind(&client, (const struct sockaddr*) &addr2, 0); - ASSERT(r == 0); + ASSERT_EQ(r, 0); r = uv_udp_recv_start(&client, alloc_cb, recv_cb); - ASSERT(r == 0); + ASSERT_EQ(r, 0); /* client sends "PING", then "PANG" */ buf = uv_buf_init("PING", 4); @@ -126,7 +143,7 @@ TEST_IMPL(udp_send_unreachable) { 1, (const struct sockaddr*) &addr, send_cb); - ASSERT(r == 0); + ASSERT_EQ(r, 0); buf = uv_buf_init("PANG", 4); @@ -136,14 +153,48 @@ TEST_IMPL(udp_send_unreachable) { 1, (const struct sockaddr*) &addr, send_cb); - ASSERT(r == 0); + ASSERT_EQ(r, 0); + + if (can_recverr) { + r = uv_udp_init(uv_default_loop(), &client2); + ASSERT_EQ(r, 0); + + r = uv_udp_bind(&client2, + (const struct sockaddr*) &addr3, + UV_UDP_LINUX_RECVERR); + ASSERT_EQ(r, 0); + + r = uv_udp_recv_start(&client2, alloc_cb, recv_cb); + ASSERT_EQ(r, 0); + + /* client sends "PING", then "PANG" */ + buf = uv_buf_init("PING", 4); + + r = uv_udp_send(&req3, + &client2, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb_recverr); + ASSERT_EQ(r, 0); + + buf = uv_buf_init("PANG", 4); + + r = uv_udp_send(&req4, + &client2, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb_recverr); + ASSERT_EQ(r, 0); + } uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(send_cb_called == 2); - ASSERT(recv_cb_called == alloc_cb_called); - ASSERT(timer_cb_called == 1); - ASSERT(close_cb_called == 2); + ASSERT_EQ(send_cb_called, (long)(can_recverr ? 4 : 2)); + ASSERT_EQ(recv_cb_called, alloc_cb_called); + ASSERT_EQ(timer_cb_called, 1); + ASSERT_EQ(close_cb_called, (long)(can_recverr ? 3 : 2)); MAKE_VALGRIND_HAPPY(); return 0; diff --git a/deps/uv/test/test-udp-try-send.c b/deps/uv/test/test-udp-try-send.c index a31d3822955632..85caaaca41d5a5 100644 --- a/deps/uv/test/test-udp-try-send.c +++ b/deps/uv/test/test-udp-try-send.c @@ -63,12 +63,12 @@ static void sv_recv_cb(uv_udp_t* handle, ASSERT(nread > 0); if (nread == 0) { - ASSERT(addr == NULL); + ASSERT_NULL(addr); return; } ASSERT(nread == 4); - ASSERT(addr != NULL); + ASSERT_NOT_NULL(addr); ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0); uv_close((uv_handle_t*) handle, close_cb); diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 7fc7e0601b9f6a..f03b4b4c0f3a20 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -238,6 +238,7 @@ [ 'OS=="linux"', { 'defines': [ '_GNU_SOURCE' ], 'sources': [ + 'src/unix/epoll.c', 'src/unix/linux-core.c', 'src/unix/linux-inotify.c', 'src/unix/linux-syscalls.c', @@ -274,6 +275,7 @@ 'defines': [ '__EXTENSIONS__', '_XOPEN_SOURCE=500', + '_REENTRANT', ], 'link_settings': { 'libraries': [ diff --git a/deps/v8/src/objects/contexts.cc b/deps/v8/src/objects/contexts.cc index eade27d934b776..6c700257059a59 100644 --- a/deps/v8/src/objects/contexts.cc +++ b/deps/v8/src/objects/contexts.cc @@ -547,7 +547,15 @@ void NativeContext::RunPromiseHook(PromiseHookType type, Handle receiver = isolate->global_proxy(); - if (Execution::Call(isolate, hook, receiver, argc, argv).is_null()) { + StackLimitCheck check(isolate); + bool failed = false; + if (check.HasOverflowed()) { + isolate->StackOverflow(); + failed = true; + } else { + failed = Execution::Call(isolate, hook, receiver, argc, argv).is_null(); + } + if (failed) { DCHECK(isolate->has_pending_exception()); Handle exception(isolate->pending_exception(), isolate); diff --git a/deps/v8/test/mjsunit/promise-hooks.js b/deps/v8/test/mjsunit/promise-hooks.js index f7c1558c1d2e20..c30a3f36da0b5c 100644 --- a/deps/v8/test/mjsunit/promise-hooks.js +++ b/deps/v8/test/mjsunit/promise-hooks.js @@ -273,3 +273,11 @@ exceptions(); d8.promise.setHooks(); })(); + +(function overflow(){ + d8.promise.setHooks(() => { new Promise(()=>{}) }); + // Trigger overflow from JS code: + Promise.all([Promise.resolve(1)]); + %PerformMicrotaskCheckpoint(); + d8.promise.setHooks(); +}); diff --git a/doc/api/async_context.md b/doc/api/async_context.md index 20cf08c06b13a4..391ed4c5459da1 100644 --- a/doc/api/async_context.md +++ b/doc/api/async_context.md @@ -1,5 +1,7 @@ # Asynchronous Context Tracking + + > Stability: 2 - Stable diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index 851b3fe3a907fc..02bb9d3001bb28 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -374,14 +374,14 @@ net.createServer((conn) => {}).listen(8080); ```cjs const { createHook, executionAsyncId } = require('async_hooks'); -const { fd } = require('process').stdout; +const { stdout } = require('process'); const net = require('net'); createHook({ init(asyncId, type, triggerAsyncId) { const eid = executionAsyncId(); fs.writeSync( - fd, + stdout.fd, `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`); } }).enable(); diff --git a/doc/api/buffer.md b/doc/api/buffer.md index a8a7635dbdc748..483265f385961d 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -459,14 +459,20 @@ multiple worker threads. ### `new buffer.Blob([sources[, options]])` * `sources` {string[]|ArrayBuffer[]|TypedArray[]|DataView[]|Blob[]} An array of string, {ArrayBuffer}, {TypedArray}, {DataView}, or {Blob} objects, or any mix of such objects, that will be stored within the `Blob`. * `options` {Object} - * `encoding` {string} The character encoding to use for string sources. - **Default:** `'utf8'`. + * `endings` {string} One of either `'transparent'` or `'native'`. When set + to `'native'`, line endings in string source parts will be converted to + the platform native line-ending as specified by `require('os').EOL`. * `type` {string} The Blob content-type. The intent is for `type` to convey the MIME media type of the data, however no validation of the type format is performed. @@ -476,7 +482,9 @@ Creates a new `Blob` object containing a concatenation of the given sources. {ArrayBuffer}, {TypedArray}, {DataView}, and {Buffer} sources are copied into the 'Blob' and can therefore be safely modified after the 'Blob' is created. -String sources are also copied into the `Blob`. +String sources are encoded as UTF-8 byte sequences and copied into the Blob. +Unmatched surrogate pairs within each string part will be replaced by Unicode +U+FFFD replacement characters. ### `blob.arrayBuffer()` + +* Returns: {ReadableStream} + +Returns a new `ReadableStream` that allows the content of the `Blob` to be read. + ### `blob.text()` + +> Stability: 1 - Experimental + +* `id` {string} A `'blob:nodedata:...` URL string returned by a prior call to + `URL.createObjectURL()`. +* Returns: {Blob} + +Resolves a `'blob:nodedata:...'` an associated {Blob} object registered using +a prior call to `URL.createObjectURL()`. + ### `buffer.transcode(source, fromEnc, toEnc)` -Node.js includes an out-of-process debugging utility accessible via a -[V8 Inspector][] and built-in debugging client. To use it, start Node.js -with the `inspect` argument followed by the path to the script to debug; a -prompt will be displayed indicating successful launch of the debugger: +Node.js includes a command-line debugging utility. To use it, start Node.js +with the `inspect` argument followed by the path to the script to debug. ```console $ node inspect myscript.js -< Debugger listening on ws://127.0.0.1:9229/80e7a814-7cd3-49fb-921a-2e02228cd5ba +< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8 < For help, see: https://nodejs.org/en/docs/inspector +< < Debugger attached. -Break on start in myscript.js:1 -> 1 (function (exports, require, module, __filename, __dirname) { global.x = 5; - 2 setTimeout(() => { - 3 console.log('world'); +< + ok +Break on start in myscript.js:2 + 1 // myscript.js +> 2 global.x = 5; + 3 setTimeout(() => { + 4 debugger; debug> ``` @@ -44,28 +46,33 @@ Once the debugger is run, a breakpoint will occur at line 3: ```console $ node inspect myscript.js -< Debugger listening on ws://127.0.0.1:9229/80e7a814-7cd3-49fb-921a-2e02228cd5ba +< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8 < For help, see: https://nodejs.org/en/docs/inspector +< < Debugger attached. -Break on start in myscript.js:1 -> 1 (function (exports, require, module, __filename, __dirname) { global.x = 5; - 2 setTimeout(() => { - 3 debugger; +< + ok +Break on start in myscript.js:2 + 1 // myscript.js +> 2 global.x = 5; + 3 setTimeout(() => { + 4 debugger; debug> cont < hello -break in myscript.js:3 - 1 (function (exports, require, module, __filename, __dirname) { global.x = 5; - 2 setTimeout(() => { -> 3 debugger; - 4 console.log('world'); - 5 }, 1000); -debug> next +< break in myscript.js:4 - 2 setTimeout(() => { - 3 debugger; -> 4 console.log('world'); - 5 }, 1000); - 6 console.log('hello'); + 2 global.x = 5; + 3 setTimeout(() => { +> 4 debugger; + 5 console.log('world'); + 6 }, 1000); +debug> next +break in myscript.js:5 + 3 setTimeout(() => { + 4 debugger; +> 5 console.log('world'); + 6 }, 1000); + 7 console.log('hello'); debug> repl Press Ctrl+C to leave debug repl > x @@ -74,13 +81,15 @@ Press Ctrl+C to leave debug repl 4 debug> next < world -break in myscript.js:5 - 3 debugger; - 4 console.log('world'); -> 5 }, 1000); - 6 console.log('hello'); - 7 +< +break in myscript.js:6 + 4 debugger; + 5 console.log('world'); +> 6 }, 1000); + 7 console.log('hello'); + 8 debug> .exit +$ ``` The `repl` command allows code to be evaluated remotely. The `next` command @@ -129,11 +138,14 @@ is not loaded yet: ```console $ node inspect main.js -< Debugger listening on ws://127.0.0.1:9229/4e3db158-9791-4274-8909-914f7facf3bd +< Debugger listening on ws://127.0.0.1:9229/48a5b28a-550c-471b-b5e1-d13dd7165df9 < For help, see: https://nodejs.org/en/docs/inspector +< < Debugger attached. +< + ok Break on start in main.js:1 -> 1 (function (exports, require, module, __filename, __dirname) { const mod = require('./mod.js'); +> 1 const mod = require('./mod.js'); 2 mod.hello(); 3 mod.hello(); debug> setBreakpoint('mod.js', 22) @@ -239,6 +251,5 @@ Chrome DevTools doesn't support debugging [worker threads][] yet. [ndb][] can be used to debug them. [Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/ -[V8 Inspector]: #debugger_v8_inspector_integration_for_node_js [ndb]: https://github.com/GoogleChromeLabs/ndb/ [worker threads]: worker_threads.md diff --git a/doc/api/dns.md b/doc/api/dns.md index 52aa4b846032e7..59082c81a0977e 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -97,6 +97,9 @@ The following methods from the `dns` module are available: + +An attempt was made to copy a directory to a non-directory (file, symlink, +etc.) using [`fs.cp()`][]. + + +### `ERR_FS_CP_EEXIST` + + +An attempt was made to copy over a file that already existed with +[`fs.cp()`][], with the `force` and `errorOnExist` set to `true`. + + +### `ERR_FS_CP_EINVAL` + + +When using [`fs.cp()`][], `src` or `dest` pointed to an invalid path. + + +### `ERR_FS_CP_FIFO_PIPE` + + +An attempt was made to copy a named pipe with [`fs.cp()`][]. + + +### `ERR_FS_CP_NON_DIR_TO_DIR` + + +An attempt was made to copy a non-directory (file, symlink, etc.) to a directory +using [`fs.cp()`][]. + + +### `ERR_FS_CP_SOCKET` + + +An attempt was made to copy to a socket with [`fs.cp()`][]. + + +### `ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY` + + +When using [`fs.cp()`][], a symlink in `dest` pointed to a subdirectory +of `src`. + + +### `ERR_FS_CP_UNKNOWN` + + +An attempt was made to copy to an unknown file type with [`fs.cp()`][]. + ### `ERR_FS_EISDIR` @@ -2814,6 +2882,7 @@ The native call from `process.cpuUsage` could not be processed. [`dgram.remoteAddress()`]: dgram.md#dgram_socket_remoteaddress [`errno`(3) man page]: https://man7.org/linux/man-pages/man3/errno.3.html [`fs.Dir`]: fs.md#fs_class_fs_dir +[`fs.cp()`]: fs.md#fs_fs_cp_src_dest_options_callback [`fs.readFileSync`]: fs.md#fs_fs_readfilesync_path_options [`fs.readdir`]: fs.md#fs_fs_readdir_path_options_callback [`fs.symlink()`]: fs.md#fs_fs_symlink_target_path_type_callback diff --git a/doc/api/fs.md b/doc/api/fs.md index a4945718bb7ee1..209fa8e6ec119d 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -693,6 +693,37 @@ try { } ``` +### `fsPromises.cp(src, dest[, options])` + + +> Stability: 1 - Experimental + +* `src` {string|URL} source path to copy. +* `dest` {string|URL} destination path to copy to. +* `options` {Object} + * `dereference` {boolean} dereference symlinks. **Default:** `false`. + * `errorOnExist` {boolean} when `force` is `false`, and the destination + exists, throw an error. **Default:** `false`. + * `filter` {Function} Function to filter copied files/directories. Return + `true` to copy the item, `false` to ignore it. Can also return a `Promise` + that resolves to `true` or `false` **Default:** `undefined`. + * `force` {boolean} overwrite existing file or directory. _The copy + operation will ignore errors if you set this to false and the destination + exists. Use the `errorOnExist` option to change this behavior. + **Default:** `true`. + * `preserveTimestamps` {boolean} When `true` timestamps from `src` will + be preserved. **Default:** `false`. + * `recursive` {boolean} copy directories recursively **Default:** `false` +* Returns: {Promise} Fulfills with `undefined` upon success. + +Asynchronously copies the entire directory structure from `src` to `dest`, +including subdirectories and files. + +When copying a directory to another directory, globs are not supported and +behavior is similar to `cp dir1/ dir2/`. + ### `fsPromises.lchmod(path, mode)` + +> Stability: 1 - Experimental + +* `src` {string|URL} source path to copy. +* `dest` {string|URL} destination path to copy to. +* `options` {Object} + * `dereference` {boolean} dereference symlinks. **Default:** `false`. + * `errorOnExist` {boolean} when `force` is `false`, and the destination + exists, throw an error. **Default:** `false`. + * `filter` {Function} Function to filter copied files/directories. Return + `true` to copy the item, `false` to ignore it. Can also return a `Promise` + that resolves to `true` or `false` **Default:** `undefined`. + * `force` {boolean} overwrite existing file or directory. _The copy + operation will ignore errors if you set this to false and the destination + exists. Use the `errorOnExist` option to change this behavior. + **Default:** `true`. + * `preserveTimestamps` {boolean} When `true` timestamps from `src` will + be preserved. **Default:** `false`. + * `recursive` {boolean} copy directories recursively **Default:** `false` +* `callback` {Function} + +Asynchronously copies the entire directory structure from `src` to `dest`, +including subdirectories and files. + +When copying a directory to another directory, globs are not supported and +behavior is similar to `cp dir1/ dir2/`. + ### `fs.createReadStream(path[, options])` + +> Stability: 1 - Experimental + +* `src` {string|URL} source path to copy. +* `dest` {string|URL} destination path to copy to. +* `options` {Object} + * `dereference` {boolean} dereference symlinks. **Default:** `false`. + * `errorOnExist` {boolean} when `force` is `false`, and the destination + exists, throw an error. **Default:** `false`. + * `filter` {Function} Function to filter copied files/directories. Return + `true` to copy the item, `false` to ignore it. **Default:** `undefined` + * `force` {boolean} overwrite existing file or directory. _The copy + operation will ignore errors if you set this to false and the destination + exists. Use the `errorOnExist` option to change this behavior. + **Default:** `true`. + * `preserveTimestamps` {boolean} When `true` timestamps from `src` will + be preserved. **Default:** `false`. + * `recursive` {boolean} copy directories recursively **Default:** `false` + +Synchronously copies the entire directory structure from `src` to `dest`, +including subdirectories and files. + +When copying a directory to another directory, globs are not supported and +behavior is similar to `cp dir1/ dir2/`. + ### `fs.existsSync(path)` + +* {boolean} + +Allows determining if the stream has been or is about to be read. +Returns true if `'data'`, `'end'`, `'error'` or `'close'` has been +emitted. + ##### `readable.readableEncoding` + +> Stability: 1 - Experimental + +* `blob` {Blob} +* Returns: {string} + +Creates a `'blob:nodedata:...'` URL string that represents the given {Blob} +object and can be used to retrieve the `Blob` later. + +```js +const { + Blob, + resolveObjectURL, +} = require('buffer'); + +const blob = new Blob(['hello']); +const id = URL.createObjectURL(blob); + +// later... + +const otherBlob = resolveObjectURL(id); +console.log(otherBlob.size); +``` + +The data stored by the registered {Blob} will be retained in memory until +`URL.revokeObjectURL()` is called to remove it. + +`Blob` objects are registered within the current thread. If using Worker +Threads, `Blob` objects registered within one Worker will not be available +to other workers or the main thread. + +#### `URL.revokeObjectURL(id)` + + +> Stability: 1 - Experimental + +* `id` {string} A `'blob:nodedata:...` URL string returned by a prior call to + `URL.createObjectURL()`. + +Removes the stored {Blob} identified by the given ID. + ### Class: `URLSearchParams` + +* Returns: {string} + +Generates a random [RFC 4122][] version 4 UUID. The UUID is generated using a +cryptographic pseudorandom number generator. + ## Class: `CryptoKey` -* Type: {string} Must be `'HMAC`. +* Type: {string} Must be `'HMAC'`. ### Class: `Pbkdf2ImportParams` + > Stability: 1 - Experimental An implementation of the [WHATWG Streams Standard][]. @@ -1217,5 +1219,129 @@ added: v16.6.0 * Type: {WritableStream} +### Class: `CompressionStream` + +#### `new CompressionStream(format)` + + +* `format` {string} One of either `'deflate'` or `'gzip'`. + +#### `compressionStream.readable` + + +* Type: {ReadableStream} + +#### `compressionStream.writable` + + +* Type: {WritableStream} + +### Class: `DecompressionStream` + + +#### `new DecompressionStream(format)` + + +* `format` {string} One of either `'deflate'` or `'gzip'`. + +#### `decompressionStream.readable` + + +* Type: {ReadableStream} + +#### `deccompressionStream.writable` + + +* Type: {WritableStream} + +### Utility Consumers + + +The utility consumer functions provide common options for consuming +streams. + +They are accessed using: + +```mjs +import { + arrayBuffer, + blob, + json, + text, +} from 'node:stream/consumers'; +``` + +```cjs +const { + arrayBuffer, + blob, + json, + text, +} = require('stream/consumers'); +``` + +#### `streamConsumers.arrayBuffer(stream)` + + +* `stream` {ReadableStream|stream.Readable|AsyncIterator} +* Returns: {Promise} Fulfills with an `ArrayBuffer` containing the full + contents of the stream. + +#### `streamConsumers.blob(stream)` + + +* `stream` {ReadableStream|stream.Readable|AsyncIterator} +* Returns: {Promise} Fulfills with a {Blob} containing the full contents + of the stream. + +#### `streamConsumers.buffer(stream)` + + +* `stream` {ReadableStream|stream.Readable|AsyncIterator} +* Returns: {Promise} Fulfills with a {Buffer} containing the full + contents of the stream. + +#### `streamConsumers.json(stream)` + + +* `stream` {ReadableStream|stream.Readable|AsyncIterator} +* Returns: {Promise} Fulfills with the contents of the stream parsed as a + UTF-8 encoded string that is then passed through `JSON.parse()`. + +#### `streamConsumers.text(stream)` + + +* `stream` {ReadableStream|stream.Readable|AsyncIterator} +* Returns: {Promise} Fulfills with the contents of the stream parsed as a + UTF-8 encoded string. + [Streams]: stream.md [WHATWG Streams Standard]: https://streams.spec.whatwg.org/ diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index b1c8a763a638aa..97215226d5582b 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -11,7 +11,7 @@ --red1: #d60027; --red2: #d50027; --red3: #ca5010; - --green1: #43853d; + --green1: #3e7a38; --green2: #5a8147; --green3: #64de64; --green4: #99cc7d; diff --git a/doc/changelogs/CHANGELOG_V16.md b/doc/changelogs/CHANGELOG_V16.md index 62fb2d99eab9d2..bf0e5010262de2 100644 --- a/doc/changelogs/CHANGELOG_V16.md +++ b/doc/changelogs/CHANGELOG_V16.md @@ -10,6 +10,7 @@ +16.7.0
16.6.2
16.6.1
16.6.0
@@ -43,6 +44,135 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2021-08-17, Version 16.7.0 (Current), @danielleadams + +### Notable Changes + +* **fs**: + * experimental: add recursive cp method (Benjamin Coe) [#39372](https://github.com/nodejs/node/pull/39372) + +### Commits + +* [[`a80c989306`](https://github.com/nodejs/node/commit/a80c989306)] - **async_hooks**: merge resource\_symbol with owner\_symbol (Darshan Sen) [#38468](https://github.com/nodejs/node/pull/38468) +* [[`69a2a6b6c3`](https://github.com/nodejs/node/commit/69a2a6b6c3)] - **bootstrap**: call \_undestroy() inside \_destroy for stdout and stderr (Matteo Collina) [#39685](https://github.com/nodejs/node/pull/39685) +* [[`5bc31ea0aa`](https://github.com/nodejs/node/commit/5bc31ea0aa)] - **buffer**: add endings option, remove Node.js specific encoding option (James M Snell) [#39708](https://github.com/nodejs/node/pull/39708) +* [[`091a579275`](https://github.com/nodejs/node/commit/091a579275)] - **(SEMVER-MINOR)** **buffer**: add Blob.prototype.stream method and other cleanups (James M Snell) [#39693](https://github.com/nodejs/node/pull/39693) +* [[`097d898e58`](https://github.com/nodejs/node/commit/097d898e58)] - **build**: run coverage for inspector protocol changes (Richard Lau) [#39725](https://github.com/nodejs/node/pull/39725) +* [[`cf028df0ed`](https://github.com/nodejs/node/commit/cf028df0ed)] - **build**: fix V8 build with pointer compression (Michaël Zasso) [#39664](https://github.com/nodejs/node/pull/39664) +* [[`9d38400de1`](https://github.com/nodejs/node/commit/9d38400de1)] - **build**: exclude markdown files from some GitHub Actions (Rich Trott) [#39565](https://github.com/nodejs/node/pull/39565) +* [[`eeb804a7b7`](https://github.com/nodejs/node/commit/eeb804a7b7)] - **build**: use lts shorthand in GitHub Actions (Rich Trott) [#39538](https://github.com/nodejs/node/pull/39538) +* [[`93a904d0ba`](https://github.com/nodejs/node/commit/93a904d0ba)] - **(SEMVER-MINOR)** **crypto**: implement webcrypto.randomUUID (Michaël Zasso) [#39648](https://github.com/nodejs/node/pull/39648) +* [[`3321b65a5a`](https://github.com/nodejs/node/commit/3321b65a5a)] - **debugger**: prevent simultaneous heap snapshots (Rich Trott) [#39638](https://github.com/nodejs/node/pull/39638) +* [[`6c375e18b6`](https://github.com/nodejs/node/commit/6c375e18b6)] - **debugger**: remove undefined parameter (Rich Trott) [#39570](https://github.com/nodejs/node/pull/39570) +* [[`103bf20988`](https://github.com/nodejs/node/commit/103bf20988)] - **deps**: V8: cherry-pick 81814ed44574 (Stephen Belanger) [#39719](https://github.com/nodejs/node/pull/39719) +* [[`cf5e5b5711`](https://github.com/nodejs/node/commit/cf5e5b5711)] - **deps**: upgrade to libuv 1.42.0 (Luigi Pinca) [#39525](https://github.com/nodejs/node/pull/39525) +* [[`5f92d2fe6d`](https://github.com/nodejs/node/commit/5f92d2fe6d)] - **dgram**: use simplified validator (Voltrex) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`c7e918b06a`](https://github.com/nodejs/node/commit/c7e918b06a)] - **(SEMVER-MINOR)** **dns**: add "tries" option to Resolve options (Luan Devecchi) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`5d66646b71`](https://github.com/nodejs/node/commit/5d66646b71)] - **doc**: correct cjs code to match mjs code (Raz Luvaton) [#39509](https://github.com/nodejs/node/pull/39509) +* [[`f18bb2a0f1`](https://github.com/nodejs/node/commit/f18bb2a0f1)] - **doc**: fix typo in hmac.paramNames default (Justin) [#39766](https://github.com/nodejs/node/pull/39766) +* [[`338a166e83`](https://github.com/nodejs/node/commit/338a166e83)] - **doc**: fix `fs.rmdir` `recursive` option deprecation history (Antoine du Hamel) [#39728](https://github.com/nodejs/node/pull/39728) +* [[`bfb1dc0a2c`](https://github.com/nodejs/node/commit/bfb1dc0a2c)] - **doc**: fixed variable names in queueMicrotask example (ashish maurya) [#39634](https://github.com/nodejs/node/pull/39634) +* [[`08b31f12f8`](https://github.com/nodejs/node/commit/08b31f12f8)] - **doc**: change "Version 4 UUID" to "version 4 UUID" (Tobias Nießen) [#39682](https://github.com/nodejs/node/pull/39682) +* [[`f5200f9785`](https://github.com/nodejs/node/commit/f5200f9785)] - **doc**: update debugger.md description and examples (Rich Trott) [#39661](https://github.com/nodejs/node/pull/39661) +* [[`4700f1e529`](https://github.com/nodejs/node/commit/4700f1e529)] - **doc**: fix color contrast issue in light mode (Rich Trott) [#39660](https://github.com/nodejs/node/pull/39660) +* [[`88c83a4698`](https://github.com/nodejs/node/commit/88c83a4698)] - **(SEMVER-MINOR)** **doc**: add missing change to resolver ctor (Luan Devecchi) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`760cafa5ed`](https://github.com/nodejs/node/commit/760cafa5ed)] - **doc**: fix typo in `url.md` (Howie Zhao) [#39666](https://github.com/nodejs/node/pull/39666) +* [[`9ab5503693`](https://github.com/nodejs/node/commit/9ab5503693)] - **doc**: add point to ask H1 reporter about credit (Daniel Bevenius) [#39585](https://github.com/nodejs/node/pull/39585) +* [[`7514405456`](https://github.com/nodejs/node/commit/7514405456)] - **doc**: update min mac ver + move mac arm64 to tier 1 (Ash Cripps) [#39586](https://github.com/nodejs/node/pull/39586) +* [[`d7c8c6dcee`](https://github.com/nodejs/node/commit/d7c8c6dcee)] - **doc**: add missing `introduced_in` metadata (Richard Lau) [#39575](https://github.com/nodejs/node/pull/39575) +* [[`8072517097`](https://github.com/nodejs/node/commit/8072517097)] - **doc**: add code examples to `Writable.destroy()` and `Writable.destroyed` (Juan José Arboleda) [#39491](https://github.com/nodejs/node/pull/39491) +* [[`55f47cc2d0`](https://github.com/nodejs/node/commit/55f47cc2d0)] - **doc**: add `String.prototype.at` and `%TypedArray%.prototype.at` (Jordan Harband) [#39583](https://github.com/nodejs/node/pull/39583) +* [[`0c0412e2c4`](https://github.com/nodejs/node/commit/0c0412e2c4)] - **doc**: move `NODE_MODULE_VERSION` in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`5df74f9b21`](https://github.com/nodejs/node/commit/5df74f9b21)] - **doc**: remove outdated ARM information from release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`8eccb11ea0`](https://github.com/nodejs/node/commit/8eccb11ea0)] - **doc**: fence command examples in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`0bd97e1f2d`](https://github.com/nodejs/node/commit/0bd97e1f2d)] - **doc**: update backport labels in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`2129ad6a0a`](https://github.com/nodejs/node/commit/2129ad6a0a)] - **doc**: add code example to `fs.truncate` method (Juan José Arboleda) [#39454](https://github.com/nodejs/node/pull/39454) +* [[`3ff5e153ef`](https://github.com/nodejs/node/commit/3ff5e153ef)] - **doc**: add code example to `http.createServer` method (Juan José Arboleda) [#39455](https://github.com/nodejs/node/pull/39455) +* [[`7d0c869cfa`](https://github.com/nodejs/node/commit/7d0c869cfa)] - **doc**: add PerformanceObserver `buffered` document (legendecas) [#39514](https://github.com/nodejs/node/pull/39514) +* [[`0dc167a03f`](https://github.com/nodejs/node/commit/0dc167a03f)] - **(SEMVER-MINOR)** **fs**: add recursive cp method (Benjamin Coe) [#39372](https://github.com/nodejs/node/pull/39372) +* [[`54dd3df943`](https://github.com/nodejs/node/commit/54dd3df943)] - **http**: decodes url.username and url.password for authorization header (Lew Gordon) [#39310](https://github.com/nodejs/node/pull/39310) +* [[`81e62f67bf`](https://github.com/nodejs/node/commit/81e62f67bf)] - **inspector**: update inspector\_protocol to 89c4adf (Rich Trott) [#39650](https://github.com/nodejs/node/pull/39650) +* [[`793fee4915`](https://github.com/nodejs/node/commit/793fee4915)] - **inspector**: update inspector\_protocol to 8ec18cf (Rich Trott) [#39614](https://github.com/nodejs/node/pull/39614) +* [[`5afdc1f4c0`](https://github.com/nodejs/node/commit/5afdc1f4c0)] - **lib**: simplify validators (Voltrex) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`ca3cb96d25`](https://github.com/nodejs/node/commit/ca3cb96d25)] - **lib**: cleanup validation (Voltrex) [#39652](https://github.com/nodejs/node/pull/39652) +* [[`cc08d3062f`](https://github.com/nodejs/node/commit/cc08d3062f)] - **lib**: cleanup instance validation (Voltrex) [#39656](https://github.com/nodejs/node/pull/39656) +* [[`2751cdf6f9`](https://github.com/nodejs/node/commit/2751cdf6f9)] - **lib**: use helper for readability (Voltrex) [#39649](https://github.com/nodejs/node/pull/39649) +* [[`c68415cba2`](https://github.com/nodejs/node/commit/c68415cba2)] - **lib**: use validators (Voltrex) [#39663](https://github.com/nodejs/node/pull/39663) +* [[`be2d60dd1d`](https://github.com/nodejs/node/commit/be2d60dd1d)] - **lib**: use validator (Voltrex) [#39547](https://github.com/nodejs/node/pull/39547) +* [[`486d51ac0c`](https://github.com/nodejs/node/commit/486d51ac0c)] - **lib**: use `validateObject` (Voltrex) [#39605](https://github.com/nodejs/node/pull/39605) +* [[`058e882a2a`](https://github.com/nodejs/node/commit/058e882a2a)] - **lib**: use ERR\_ILLEGAL\_CONSTRUCTOR (Mestery) [#39556](https://github.com/nodejs/node/pull/39556) +* [[`07cadc4432`](https://github.com/nodejs/node/commit/07cadc4432)] - **meta**: consolidate AUTHORS entries for ooHmartY (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`6c788b8030`](https://github.com/nodejs/node/commit/6c788b8030)] - **meta**: consolidate AUTHORS entries for homosaur (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`07351edebe`](https://github.com/nodejs/node/commit/07351edebe)] - **meta**: consolidate AUTHORS entries for Ayase-252 (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`5fe282769b`](https://github.com/nodejs/node/commit/5fe282769b)] - **meta**: consolidate AUTHORS entries for robin-drexler (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`fc2a626357`](https://github.com/nodejs/node/commit/fc2a626357)] - **meta**: consolidate AUTHORS entries for samshull (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`67cfc66a47`](https://github.com/nodejs/node/commit/67cfc66a47)] - **meta**: update AUTHORS (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`91008fbdeb`](https://github.com/nodejs/node/commit/91008fbdeb)] - **meta**: consolidate email addresses for MarshallOfSound (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`a76b63536a`](https://github.com/nodejs/node/commit/a76b63536a)] - **meta**: consolidate email addresses for tadjik1 (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`aaab2095db`](https://github.com/nodejs/node/commit/aaab2095db)] - **meta**: consolidate email addresses for szmarczak (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`f413a9d83c`](https://github.com/nodejs/node/commit/f413a9d83c)] - **meta**: update AUTHORS (Rich Trott) [#39636](https://github.com/nodejs/node/pull/39636) +* [[`7a91d4bfe9`](https://github.com/nodejs/node/commit/7a91d4bfe9)] - **meta**: simplify mailmap (Rich Trott) [#39612](https://github.com/nodejs/node/pull/39612) +* [[`4ec5d2de5d`](https://github.com/nodejs/node/commit/4ec5d2de5d)] - **meta**: consolidate emails for tadhgcreedon (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`bb88c38eac`](https://github.com/nodejs/node/commit/bb88c38eac)] - **meta**: consolidate emails for timcosta (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`0920a8cf6f`](https://github.com/nodejs/node/commit/0920a8cf6f)] - **meta**: consolidate emails for timruffles (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`1474a9d4b1`](https://github.com/nodejs/node/commit/1474a9d4b1)] - **meta**: update AUTHORS (Rich Trott) [#39629](https://github.com/nodejs/node/pull/39629) +* [[`c59e3ec685`](https://github.com/nodejs/node/commit/c59e3ec685)] - **meta**: add mailmap entry for ryzokuken (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`34f4bb8277`](https://github.com/nodejs/node/commit/34f4bb8277)] - **meta**: add mailmap entry for uttampawar (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`fd213edda2`](https://github.com/nodejs/node/commit/fd213edda2)] - **meta**: add mailmap entry for dmabupt (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`6b664e224b`](https://github.com/nodejs/node/commit/6b664e224b)] - **meta**: align README/.mailmap/AUTHORS email entries (Rich Trott) [#39505](https://github.com/nodejs/node/pull/39505) +* [[`96d8ecbd66`](https://github.com/nodejs/node/commit/96d8ecbd66)] - **meta**: add mailmap entry for garygsc (Rich Trott) [#39588](https://github.com/nodejs/node/pull/39588) +* [[`16d85f3f48`](https://github.com/nodejs/node/commit/16d85f3f48)] - **meta**: add mailmap entry for ttzztztz (Rich Trott) [#39588](https://github.com/nodejs/node/pull/39588) +* [[`60ab111fdb`](https://github.com/nodejs/node/commit/60ab111fdb)] - **meta**: update AUTHORS (Rich Trott) [#39587](https://github.com/nodejs/node/pull/39587) +* [[`b43f87d729`](https://github.com/nodejs/node/commit/b43f87d729)] - **meta**: update .mailmap to remove duplication in AUTHORS (Rich Trott) [#39561](https://github.com/nodejs/node/pull/39561) +* [[`6f4a2aa5a4`](https://github.com/nodejs/node/commit/6f4a2aa5a4)] - **meta**: add .mailmap entries to remove AUTHORS duplicates (Rich Trott) [#39560](https://github.com/nodejs/node/pull/39560) +* [[`86d144c500`](https://github.com/nodejs/node/commit/86d144c500)] - **meta**: add .mailmap entry to remove duplication in AUTHORS (Rich Trott) [#39559](https://github.com/nodejs/node/pull/39559) +* [[`110c088f02`](https://github.com/nodejs/node/commit/110c088f02)] - **meta**: update collaborator email in AUTHORS/.mailmap (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`72af147bb5`](https://github.com/nodejs/node/commit/72af147bb5)] - **meta**: update collaborator email in README (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`23bc4cfb21`](https://github.com/nodejs/node/commit/23bc4cfb21)] - **meta**: update collaborator email in AUTHORS/.mailmap (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`e4289728c7`](https://github.com/nodejs/node/commit/e4289728c7)] - **meta**: move gdams to emeritus (Rich Trott) [#39539](https://github.com/nodejs/node/pull/39539) +* [[`4df59bc727`](https://github.com/nodejs/node/commit/4df59bc727)] - **module**: add some typings to `internal/modules/esm/resolve` (Antoine du Hamel) [#39504](https://github.com/nodejs/node/pull/39504) +* [[`b5858589d0`](https://github.com/nodejs/node/commit/b5858589d0)] - **node-api**: handle pending exception in cb wrapper (Michael Dawson) [#39476](https://github.com/nodejs/node/pull/39476) +* [[`016b7ba616`](https://github.com/nodejs/node/commit/016b7ba616)] - **perf_hooks**: fix PerformanceObserver gc crash (James M Snell) [#39550](https://github.com/nodejs/node/pull/39550) +* [[`b37575b67c`](https://github.com/nodejs/node/commit/b37575b67c)] - **perf_hooks**: fix performance timeline wpt failures (legendecas) [#39532](https://github.com/nodejs/node/pull/39532) +* [[`64c02eb3cc`](https://github.com/nodejs/node/commit/64c02eb3cc)] - **(SEMVER-MINOR)** **perf_hooks**: web performance timeline compliance (legendecas) [#39297](https://github.com/nodejs/node/pull/39297) +* [[`7ff21397d6`](https://github.com/nodejs/node/commit/7ff21397d6)] - **policy**: fix integrity when DEFAULT\_ENCODING is set (Tobias Nießen) [#39750](https://github.com/nodejs/node/pull/39750) +* [[`03be967cad`](https://github.com/nodejs/node/commit/03be967cad)] - **src**: fix TextDecoder final flush size calculation (James M Snell) [#39737](https://github.com/nodejs/node/pull/39737) +* [[`9046e78943`](https://github.com/nodejs/node/commit/9046e78943)] - **src**: fix crash in AfterGetAddrInfo (Anna Henningsen) [#39735](https://github.com/nodejs/node/pull/39735) +* [[`2a00ef5ede`](https://github.com/nodejs/node/commit/2a00ef5ede)] - **(SEMVER-MINOR)** **src**: fix align in cares\_wrap.h (Luan) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`60a2b31c68`](https://github.com/nodejs/node/commit/60a2b31c68)] - **src**: add cosmetic space character to `async_wrap.h` file (Juan José Arboleda) [#39459](https://github.com/nodejs/node/pull/39459) +* [[`cd9b0bf68c`](https://github.com/nodejs/node/commit/cd9b0bf68c)] - **stream**: ensure text() stream consumer flushes correctly (James M Snell) [#39737](https://github.com/nodejs/node/pull/39737) +* [[`f57a0e4d8b`](https://github.com/nodejs/node/commit/f57a0e4d8b)] - **(SEMVER-MINOR)** **stream**: utility consumers for web and node.js streams (James M Snell) [#39594](https://github.com/nodejs/node/pull/39594) +* [[`975edf5330`](https://github.com/nodejs/node/commit/975edf5330)] - **stream**: clean `endWritableNT` (Mestery) [#39645](https://github.com/nodejs/node/pull/39645) +* [[`9e38fc6757`](https://github.com/nodejs/node/commit/9e38fc6757)] - **(SEMVER-MINOR)** **stream**: add readableDidRead if has been read from (Robert Nagy) [#39589](https://github.com/nodejs/node/pull/39589) +* [[`a5ded4a85a`](https://github.com/nodejs/node/commit/a5ded4a85a)] - **test**: use simplfied validator (voltrexmaster) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`53cf53c95a`](https://github.com/nodejs/node/commit/53cf53c95a)] - **(SEMVER-MINOR)** **test**: enable blob.prototype.stream tests (James M Snell) [#39693](https://github.com/nodejs/node/pull/39693) +* [[`7e9884598f`](https://github.com/nodejs/node/commit/7e9884598f)] - **test**: update WPT abort tests (Michaël Zasso) [#39697](https://github.com/nodejs/node/pull/39697) +* [[`94381fbdf5`](https://github.com/nodejs/node/commit/94381fbdf5)] - **test**: update WPT common and resources (Michaël Zasso) [#39697](https://github.com/nodejs/node/pull/39697) +* [[`34a041a846`](https://github.com/nodejs/node/commit/34a041a846)] - **test**: fix test-debugger-heap-profiler for workers (Richard Lau) [#39687](https://github.com/nodejs/node/pull/39687) +* [[`9f5acfa90e`](https://github.com/nodejs/node/commit/9f5acfa90e)] - **test**: increase memory for coverage action (Benjamin Coe) [#39690](https://github.com/nodejs/node/pull/39690) +* [[`0be15cedc4`](https://github.com/nodejs/node/commit/0be15cedc4)] - **test**: use template to concatenate string (Himadri Ganguly) [#39621](https://github.com/nodejs/node/pull/39621) +* [[`952a5282e2`](https://github.com/nodejs/node/commit/952a5282e2)] - **(SEMVER-MINOR)** **test**: pull Web Platform Tests for WebCryptoAPI (Michaël Zasso) [#39648](https://github.com/nodejs/node/pull/39648) +* [[`3622fb1e03`](https://github.com/nodejs/node/commit/3622fb1e03)] - **test**: deflake test-http2-buffersize (Luigi Pinca) [#39591](https://github.com/nodejs/node/pull/39591) +* [[`1962c7c7b3`](https://github.com/nodejs/node/commit/1962c7c7b3)] - **test**: convert anonymous function to arrow function (Himadri Ganguly) [#39604](https://github.com/nodejs/node/pull/39604) +* [[`635e1a0274`](https://github.com/nodejs/node/commit/635e1a0274)] - **test**: add test-debugger-breakpoint-exists (Rich Trott) [#39570](https://github.com/nodejs/node/pull/39570) +* [[`cff2aea5df`](https://github.com/nodejs/node/commit/cff2aea5df)] - **test**: add known issues test for debugger heap snapshot race (Rich Trott) [#39557](https://github.com/nodejs/node/pull/39557) +* [[`5e1011238a`](https://github.com/nodejs/node/commit/5e1011238a)] - **tools**: bump remark-preset-lint-node to 3.0.0 (Rich Trott) [#39755](https://github.com/nodejs/node/pull/39755) +* [[`eb741253fd`](https://github.com/nodejs/node/commit/eb741253fd)] - **tools**: update path-parse in markdown linter package-lock file (Rich Trott) [#39729](https://github.com/nodejs/node/pull/39729) +* [[`52a172f983`](https://github.com/nodejs/node/commit/52a172f983)] - **tools**: fix more build warnings in inspector\_protocol (Richard Lau) [#39725](https://github.com/nodejs/node/pull/39725) +* [[`77f9c1fa98`](https://github.com/nodejs/node/commit/77f9c1fa98)] - **tools**: cherry-pick ffb34b6d5dbf0 (Darshan Sen) [#39725](https://github.com/nodejs/node/pull/39725) +* [[`b9510d21c9`](https://github.com/nodejs/node/commit/b9510d21c9)] - **tools**: update inspector\_protocol to e8ba1a7 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`8d509d8773`](https://github.com/nodejs/node/commit/8d509d8773)] - **tools**: update inspector\_protocol to 39ca567 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`ee7142fa37`](https://github.com/nodejs/node/commit/ee7142fa37)] - **tools**: update inspector\_protocol to 97d3146 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`c6323d847d`](https://github.com/nodejs/node/commit/c6323d847d)] - ***Revert*** "**tools**: fix compiler warning in inspector\_protocol" (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`6e19c166e4`](https://github.com/nodejs/node/commit/6e19c166e4)] - **tools**: update inspector\_protocol to a53e96d31a2755eb16ca37 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`61c53f39d2`](https://github.com/nodejs/node/commit/61c53f39d2)] - **tools**: update inspector\_protocol to fe0467fd105a (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`b1b6f20353`](https://github.com/nodejs/node/commit/b1b6f20353)] - **tools**: improve error detection in find-inactive-collaborators (Rich Trott) [#39617](https://github.com/nodejs/node/pull/39617) +* [[`d1360fcf48`](https://github.com/nodejs/node/commit/d1360fcf48)] - **tools**: update ESLint to 7.32.0 (Luigi Pinca) [#39602](https://github.com/nodejs/node/pull/39602) +* [[`af1c782cad`](https://github.com/nodejs/node/commit/af1c782cad)] - **tools**: update ESLint to 7.31.0 (Colin Ihrig) [#39424](https://github.com/nodejs/node/pull/39424) +* [[`37dda19461`](https://github.com/nodejs/node/commit/37dda19461)] - **(SEMVER-MINOR)** **url,buffer**: implement URL.createObjectURL (James M Snell) [#39693](https://github.com/nodejs/node/pull/39693) +* [[`dcab88ad38`](https://github.com/nodejs/node/commit/dcab88ad38)] - **worker**: add brand checks for detached properties/methods (James M Snell) [#39763](https://github.com/nodejs/node/pull/39763) + ## 2021-08-11, Version 16.6.2 (Current), @BethGriggs @@ -99,7 +229,7 @@ This is a security release. The V8 engine is updated to version 9.2.230.21. -It notably introduces the new [`Array.prototype.at`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at) method: +It notably introduces the new [`Array.prototype.at`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at) method (also on [Typed Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/at) and [strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/at)): ```js const array = [1, 2, 3]; diff --git a/doc/guides/releases.md b/doc/guides/releases.md index 8a357b595a8c89..d3c0712b73768c 100644 --- a/doc/guides/releases.md +++ b/doc/guides/releases.md @@ -175,7 +175,7 @@ duplicate or not. For a list of commits that could be landed in a patch release on v1.x: ```console -$ branch-diff v1.x-staging master --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x --filter-release --format=simple +$ branch-diff v1.x-staging master --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=simple ``` Previously released commits and version bumps do not need to be @@ -195,7 +195,7 @@ command. (For semver-minor releases, make sure to remove the `semver-minor` tag from `exclude-label`.) ```console -$ branch-diff v1.x-staging master --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x --filter-release --format=sha --reverse | xargs git cherry-pick +$ branch-diff v1.x-staging master --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=sha --reverse | xargs git cherry-pick ``` When cherry-picking commits, if there are simple conflicts you can resolve @@ -243,34 +243,6 @@ be produced with a version string that does not have a trailing pre-release tag: #define NODE_VERSION_IS_RELEASE 1 ``` -**Also consider whether to bump `NODE_MODULE_VERSION`**: - -This macro is used to signal an ABI version for native addons. It currently has -two common uses in the community: - -* Determining what API to work against for compiling native addons, e.g. - [NAN](https://github.com/nodejs/nan) uses it to form a compatibility-layer for - much of what it wraps. -* Determining the ABI for downloading pre-built binaries of native addons, e.g. - [node-pre-gyp](https://github.com/mapbox/node-pre-gyp) uses this value as - exposed via `process.versions.modules` to help determine the appropriate - binary to download at install-time. - -The general rule is to bump this version when there are _breaking ABI_ changes -and also if there are non-trivial API changes. The rules are not yet strictly -defined, so if in doubt, please confer with someone that will have a more -informed perspective, such as a member of the NAN team. - -A registry of currently used `NODE_MODULE_VERSION` values is maintained at -. -When bumping `NODE_MODULE_VERSION`, you should choose a new value not listed -in the registry. Also include a change to the registry in your commit to -reflect the newly used value. - -It is current TSC policy to bump major version when ABI changes. If you -see a need to bump `NODE_MODULE_VERSION` then you should consult the TSC. -Commits may need to be reverted or a major version bump may need to happen. - ### 4. Update the changelog #### Step 1: Collect the formatted list of changes @@ -345,10 +317,14 @@ accordingly by removing the bold styling from the previous release. If this release includes new APIs then it is necessary to document that they were first added in this version. The relevant commits should already include `REPLACEME` tags as per the example in the -[docs README](../../tools/doc/README.md). Check for these tags with `grep -REPLACEME doc/api/*.md`, and substitute this node version with `sed -i -"s/REPLACEME/$VERSION/g" doc/api/*.md` or `perl -pi -e "s/REPLACEME/$VERSION/g" -doc/api/*.md`. +[docs README](../../tools/doc/README.md). Check for these tags with +```console +grep REPLACEME doc/api/*.md +``` +and substitute this node version with +```console +sed -i "s/REPLACEME/$VERSION/g" doc/api/*.md` or `perl -pi -e "s/REPLACEME/$VERSION/g" doc/api/*.md +``` `$VERSION` should be prefixed with a `v`. @@ -471,26 +447,6 @@ minutes which will prevent Jenkins from clearing the workspace to start a new one. This isn't a big deal, it's just a hassle because it'll result in another failed build if you start again! -ARMv7 takes the longest to compile. Unfortunately ccache isn't as effective on -release builds, I think it's because of the additional macro settings that go in -to a release build that nullify previous builds. Also most of the release build -machines are separate to the test build machines so they don't get any benefit -from ongoing compiles between releases. You can expect 1.5 hours for the ARMv7 -builder to complete and you should normally wait for this to finish. It is -possible to rush a release out if you want and add additional builds later but -we normally provide ARMv7 from initial promotion. - -You do not have to wait for the ARMv6 / Raspberry PI builds if they take longer -than the others. It is only necessary to have the main Linux (x64 and x86), -macOS .pkg and .tar.gz, Windows (x64 and x86) .msi and .exe, source, headers, -and docs (both produced currently by an macOS worker). **If you promote builds -_before_ ARM builds have finished, you must repeat the promotion step for the -ARM builds when they are ready**. If the ARMv6 build failed for some reason you -can use the -[`iojs-release-arm6-only`](https://ci-release.nodejs.org/job/iojs+release-arm6-only/) -build in the release CI to re-run the build only for ARMv6. When launching the -build make sure to use the same commit hash as for the original release. - ### 10. Test the build Jenkins collects the artifacts from the builds, allowing you to download and @@ -674,11 +630,6 @@ SHASUMS256.txt.sig. directory. -If you didn't wait for ARM builds in the previous step before promoting the -release, you should re-run `tools/release.sh` after the ARM builds have -finished. That will move the ARM artifacts into the correct location. You will -be prompted to re-sign `SHASUMS256.txt`. - **It is possible to only sign a release by running `./tools/release.sh -s vX.Y.Z`.** @@ -859,6 +810,36 @@ Notify the `@nodejs/npm` team in the release proposal PR to inform them of the upcoming release. `npm` maintains a list of [supported versions](https://github.com/npm/cli/blob/latest/lib/utils/unsupported.js#L3) that will need updating to include the new major release. +### Update `NODE_MODULE_VERSION` + +This macro in `src/node_version.h` is used to signal an ABI version for native +addons. It currently has two common uses in the community: + +* Determining what API to work against for compiling native addons, e.g. + [NAN](https://github.com/nodejs/nan) uses it to form a compatibility-layer for + much of what it wraps. +* Determining the ABI for downloading pre-built binaries of native addons, e.g. + [node-pre-gyp](https://github.com/mapbox/node-pre-gyp) uses this value as + exposed via `process.versions.modules` to help determine the appropriate + binary to download at install-time. + +The general rule is to bump this version when there are _breaking ABI_ changes +and also if there are non-trivial API changes. The rules are not yet strictly +defined, so if in doubt, please confer with someone that will have a more +informed perspective, such as a member of the NAN team. + +A registry of currently used `NODE_MODULE_VERSION` values is maintained at +. +When bumping `NODE_MODULE_VERSION`, you should choose a new value not listed +in the registry. Also include a change to the registry in your commit to +reflect the newly used value. Ensure that the release commit removes the +`-pre` suffix for the major version being prepared. + +It is current TSC policy to bump major version when ABI changes. If you +see a need to bump `NODE_MODULE_VERSION` outside of a majore release then +you should consult the TSC. Commits may need to be reverted or a major +version bump may need to happen. + ### Test releases and release candidates Test builds should be generated from the `vN.x-proposal` branch starting at diff --git a/doc/guides/security-release-process.md b/doc/guides/security-release-process.md index 36ee9d73bbeb6f..42e34b4dd82548 100644 --- a/doc/guides/security-release-process.md +++ b/doc/guides/security-release-process.md @@ -21,6 +21,11 @@ information described. the date in the slug so that it will move to the top of the blog list.) * [ ] pre-release: ***LINK TO PR*** * [ ] post-release: ***LINK TO PR*** + * Ask the HackerOne reporter if they would like to be credited on the + security release blog page: + ```text + Thank you to for reporting this vulnerability. + ``` * [ ] Get agreement on the planned date for the release: ***RELEASE DATE*** diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 1e372f417ee5b2..a42c0e83992b1f 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -525,7 +525,7 @@ function asyncResetHandle(socket) { const handle = socket._handle; if (handle && typeof handle.asyncReset === 'function') { // Assign the handle a new asyncId and run any destroy()/init() hooks. - handle.asyncReset(new ReusedHandle(handle.getProviderType(), handle)); + handle.asyncReset(new ReusedHandle(handle.getProviderType(), socket)); socket[async_id_symbol] = handle.getAsyncId(); } } diff --git a/lib/buffer.js b/lib/buffer.js index 278a67cbbfb37e..1f4f0a2e89deb8 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -120,6 +120,7 @@ const { const { Blob, + resolveObjectURL, } = require('internal/blob'); FastBuffer.prototype.constructor = Buffer; @@ -1239,6 +1240,7 @@ function atob(input) { module.exports = { Blob, + resolveObjectURL, Buffer, SlowBuffer, transcode, diff --git a/lib/crypto.js b/lib/crypto.js index e2355b0f5d53f6..6e050068b2093d 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -284,7 +284,7 @@ ObjectDefineProperties(module.exports, { webcrypto: { configurable: false, enumerable: true, - get() { return lazyRequire('internal/crypto/webcrypto'); } + get() { return lazyRequire('internal/crypto/webcrypto').crypto; } }, // Aliases for randomBytes are deprecated. diff --git a/lib/dgram.js b/lib/dgram.js index 4630be4dff8c5c..c515c551427d98 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -369,7 +369,7 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { }; Socket.prototype.connect = function(port, address, callback) { - port = validatePort(port, 'Port', { allowZero: false }); + port = validatePort(port, 'Port', false); if (typeof address === 'function') { callback = address; address = ''; @@ -626,7 +626,7 @@ Socket.prototype.send = function(buffer, } if (!connected) - port = validatePort(port, 'Port', { allowZero: false }); + port = validatePort(port, 'Port', false); // Normalize callback so it's either a function or undefined but not anything // else. diff --git a/lib/fs.js b/lib/fs.js index cf3c885b31cdf8..7e126b84adec76 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -107,6 +107,7 @@ const { stringToSymlinkType, toUnixTimestamp, validateBufferArray, + validateCpOptions, validateOffsetLengthRead, validateOffsetLengthWrite, validatePath, @@ -145,6 +146,8 @@ let truncateWarn = true; let fs; // Lazy loaded +let cpFn; +let cpSyncFn; let promises = null; let ReadStream; let WriteStream; @@ -1075,6 +1078,13 @@ function ftruncateSync(fd, len = 0) { handleErrorFromBinding(ctx); } +function lazyLoadCp() { + if (cpFn === undefined) { + ({ cpFn } = require('internal/fs/cp/cp')); + cpFn = require('util').callbackify(cpFn); + ({ cpSyncFn } = require('internal/fs/cp/cp-sync')); + } +} function lazyLoadRimraf() { if (rimraf === undefined) @@ -2790,6 +2800,44 @@ function copyFileSync(src, dest, mode) { handleErrorFromBinding(ctx); } +/** + * Asynchronously copies `src` to `dest`. `src` can be a file, directory, or + * symlink. The contents of directories will be copied recursively. + * @param {string | URL} src + * @param {string | URL} dest + * @param {Object} [options] + * @param {() => any} callback + * @returns {void} + */ +function cp(src, dest, options, callback) { + if (typeof options === 'function') { + callback = options; + options = undefined; + } + callback = makeCallback(callback); + options = validateCpOptions(options); + src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); + dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + lazyLoadCp(); + cpFn(src, dest, options, callback); +} + +/** + * Synchronously copies `src` to `dest`. `src` can be a file, directory, or + * symlink. The contents of directories will be copied recursively. + * @param {string | URL} src + * @param {string | URL} dest + * @param {Object} [options] + * @returns {void} + */ +function cpSync(src, dest, options) { + options = validateCpOptions(options); + src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); + dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + lazyLoadCp(); + cpSyncFn(src, dest, options); +} + function lazyLoadStreams() { if (!ReadStream) { ({ ReadStream, WriteStream } = require('internal/fs/streams')); @@ -2854,6 +2902,8 @@ module.exports = fs = { closeSync, copyFile, copyFileSync, + cp, + cpSync, createReadStream, createWriteStream, exists, diff --git a/lib/internal/abort_controller.js b/lib/internal/abort_controller.js index e6ee07052617d5..c24963b823c683 100644 --- a/lib/internal/abort_controller.js +++ b/lib/internal/abort_controller.js @@ -10,7 +10,6 @@ const { ObjectDefineProperty, Symbol, SymbolToStringTag, - TypeError, } = primordials; const { @@ -25,6 +24,7 @@ const { const { inspect } = require('internal/util/inspect'); const { codes: { + ERR_ILLEGAL_CONSTRUCTOR, ERR_INVALID_THIS, } } = require('internal/errors'); @@ -49,8 +49,7 @@ function validateAbortSignal(obj) { class AbortSignal extends EventTarget { constructor() { - // eslint-disable-next-line no-restricted-syntax - throw new TypeError('Illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } get aborted() { diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index c5895bce1c036c..9aacf4b3bab7c4 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -81,7 +81,7 @@ const active_hooks = { const { registerDestroyHook } = async_wrap; const { enqueueMicrotask } = internalBinding('task_queue'); -const { resource_symbol, owner_symbol } = internalBinding('symbols'); +const { owner_symbol } = internalBinding('symbols'); // Each constant tracks how many callbacks there are for any given step of // async execution. These are tracked so if the user didn't include callbacks @@ -178,11 +178,13 @@ function fatalError(e) { function lookupPublicResource(resource) { if (typeof resource !== 'object' || resource === null) return resource; - // TODO(addaleax): Merge this with owner_symbol and use it across all - // AsyncWrap instances. - const publicResource = resource[resource_symbol]; - if (publicResource !== undefined) + + const publicResource = resource[owner_symbol]; + + if (publicResource != null) { return publicResource; + } + return resource; } diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 927b9f54046bf2..5fb25e04fe1abe 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -5,10 +5,14 @@ const { MathMax, MathMin, ObjectDefineProperty, - ObjectSetPrototypeOf, PromiseResolve, + PromiseReject, + SafePromisePrototypeFinally, + ReflectConstruct, + RegExpPrototypeSymbolReplace, RegExpPrototypeTest, StringPrototypeToLowerCase, + StringPrototypeSplit, Symbol, SymbolIterator, SymbolToStringTag, @@ -16,14 +20,18 @@ const { } = primordials; const { - createBlob, + createBlob: _createBlob, FixedSizeBlobCopyJob, -} = internalBinding('buffer'); + getDataObject, +} = internalBinding('blob'); -const { TextDecoder } = require('internal/encoding'); +const { + TextDecoder, + TextEncoder, +} = require('internal/encoding'); const { - JSTransferable, + makeTransferable, kClone, kDeserialize, } = require('internal/worker/js_transferable'); @@ -44,6 +52,8 @@ const { AbortError, codes: { ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_THIS, ERR_BUFFER_TOO_LARGE, } } = require('internal/errors'); @@ -54,31 +64,59 @@ const { } = require('internal/validators'); const kHandle = Symbol('kHandle'); +const kState = Symbol('kState'); const kType = Symbol('kType'); const kLength = Symbol('kLength'); +const kArrayBufferPromise = Symbol('kArrayBufferPromise'); + +const kMaxChunkSize = 65536; const disallowedTypeCharacters = /[^\u{0020}-\u{007E}]/u; -let Buffer; +let ReadableStream; +let URL; +let EOL; + +const enc = new TextEncoder(); + +// Yes, lazy loading is annoying but because of circular +// references between the url, internal/blob, and buffer +// modules, lazy loading here makes sure that things work. + +function lazyURL(id) { + URL ??= require('internal/url').URL; + return new URL(id); +} + +function lazyReadableStream(options) { + ReadableStream ??= + require('internal/webstreams/readablestream').ReadableStream; + return new ReadableStream(options); +} -function lazyBuffer() { - if (Buffer === undefined) - Buffer = require('buffer').Buffer; - return Buffer; +// TODO(@jasnell): This is annoying but this has to be lazy because +// requiring the 'os' module too early causes building Node.js to +// fail with an unknown reference failure. +function lazyEOL() { + EOL ??= require('os').EOL; + return EOL; } function isBlob(object) { return object?.[kHandle] !== undefined; } -function getSource(source, encoding) { +function getSource(source, endings) { if (isBlob(source)) return [source.size, source[kHandle]]; if (isAnyArrayBuffer(source)) { source = new Uint8Array(source); } else if (!isArrayBufferView(source)) { - source = lazyBuffer().from(`${source}`, encoding); + source = `${source}`; + if (endings === 'native') + source = RegExpPrototypeSymbolReplace(/\n|\r\n/g, source, lazyEOL()); + source = enc.encode(source); } // We copy into a new Uint8Array because the underlying @@ -89,16 +127,17 @@ function getSource(source, encoding) { return [source.byteLength, source]; } -class InternalBlob extends JSTransferable { - constructor(handle, length, type = '') { - super(); - this[kHandle] = handle; - this[kType] = type; - this[kLength] = length; - } -} - -class Blob extends JSTransferable { +class Blob { + /** + * @typedef {string|ArrayBuffer|ArrayBufferView|Blob} SourcePart + * + * @param {SourcePart[]} [sources] + * @param {{ + * endings? : string, + * type? : string, + * }} [options] + * @returns + */ constructor(sources = [], options = {}) { emitExperimentalWarning('buffer.Blob'); if (sources === null || @@ -107,12 +146,18 @@ class Blob extends JSTransferable { throw new ERR_INVALID_ARG_TYPE('sources', 'Iterable', sources); } validateObject(options, 'options'); - const { encoding = 'utf8' } = options; - let { type = '' } = options; + let { + type = '', + endings = 'transparent', + } = options; + + endings = `${endings}`; + if (endings !== 'transparent' && endings !== 'native') + throw new ERR_INVALID_ARG_VALUE('options.endings', endings); let length = 0; const sources_ = ArrayFrom(sources, (source) => { - const { 0: len, 1: src } = getSource(source, encoding); + const { 0: len, 1: src } = getSource(source, endings); length += len; return src; }); @@ -120,13 +165,15 @@ class Blob extends JSTransferable { if (!isUint32(length)) throw new ERR_BUFFER_TOO_LARGE(0xFFFFFFFF); - super(); - this[kHandle] = createBlob(sources_, length); + this[kHandle] = _createBlob(sources_, length); this[kLength] = length; type = `${type}`; this[kType] = RegExpPrototypeTest(disallowedTypeCharacters, type) ? '' : StringPrototypeToLowerCase(type); + + // eslint-disable-next-line no-constructor-return + return makeTransferable(this); } [kInspect](depth, options) { @@ -150,7 +197,7 @@ class Blob extends JSTransferable { const length = this[kLength]; return { data: { handle, type, length }, - deserializeInfo: 'internal/blob:InternalBlob' + deserializeInfo: 'internal/blob:ClonedBlob' }; } @@ -160,11 +207,35 @@ class Blob extends JSTransferable { this[kLength] = length; } - get type() { return this[kType]; } + /** + * @readonly + * @type {string} + */ + get type() { + if (!isBlob(this)) + throw new ERR_INVALID_THIS('Blob'); + return this[kType]; + } - get size() { return this[kLength]; } + /** + * @readonly + * @type {number} + */ + get size() { + if (!isBlob(this)) + throw new ERR_INVALID_THIS('Blob'); + return this[kLength]; + } + /** + * @param {number} [start] + * @param {number} [end] + * @param {string} [contentType] + * @returns {Blob} + */ slice(start = 0, end = this[kLength], contentType = '') { + if (!isBlob(this)) + throw new ERR_INVALID_THIS('Blob'); if (start < 0) { start = MathMax(this[kLength] + start, 0); } else { @@ -188,35 +259,105 @@ class Blob extends JSTransferable { const span = MathMax(end - start, 0); - return new InternalBlob( - this[kHandle].slice(start, start + span), span, contentType); + return createBlob( + this[kHandle].slice(start, start + span), + span, + contentType); } - async arrayBuffer() { + /** + * @returns {Promise} + */ + arrayBuffer() { + if (!isBlob(this)) + return PromiseReject(new ERR_INVALID_THIS('Blob')); + + // If there's already a promise in flight for the content, + // reuse it, but only while it's in flight. After the cached + // promise resolves it will be cleared, allowing it to be + // garbage collected as soon as possible. + if (this[kArrayBufferPromise]) + return this[kArrayBufferPromise]; + const job = new FixedSizeBlobCopyJob(this[kHandle]); const ret = job.run(); + + // If the job returns a value immediately, the ArrayBuffer + // was generated synchronously and should just be returned + // directly. if (ret !== undefined) return PromiseResolve(ret); const { promise, resolve, - reject + reject, } = createDeferredPromise(); + job.ondone = (err, ab) => { if (err !== undefined) return reject(new AbortError()); resolve(ab); }; + this[kArrayBufferPromise] = + SafePromisePrototypeFinally( + promise, + () => this[kArrayBufferPromise] = undefined); - return promise; + return this[kArrayBufferPromise]; } + /** + * @returns {Promise} + */ async text() { + if (!isBlob(this)) + throw new ERR_INVALID_THIS('Blob'); + const dec = new TextDecoder(); return dec.decode(await this.arrayBuffer()); } + + /** + * @returns {ReadableStream} + */ + stream() { + if (!isBlob(this)) + throw new ERR_INVALID_THIS('Blob'); + + const self = this; + return new lazyReadableStream({ + async start() { + this[kState] = await self.arrayBuffer(); + }, + + pull(controller) { + if (this[kState].byteLength <= kMaxChunkSize) { + controller.enqueue(new Uint8Array(this[kState])); + controller.close(); + this[kState] = undefined; + } else { + const slice = this[kState].slice(0, kMaxChunkSize); + this[kState] = this[kState].slice(kMaxChunkSize); + controller.enqueue(new Uint8Array(slice)); + } + } + }); + } +} + +function ClonedBlob() { + return makeTransferable(ReflectConstruct(function() {}, [], Blob)); +} +ClonedBlob.prototype[kDeserialize] = () => {}; + +function createBlob(handle, length, type = '') { + return makeTransferable(ReflectConstruct(function() { + this[kHandle] = handle; + this[kType] = type; + this[kLength] = length; + }, [], Blob)); } ObjectDefineProperty(Blob.prototype, SymbolToStringTag, { @@ -224,13 +365,47 @@ ObjectDefineProperty(Blob.prototype, SymbolToStringTag, { value: 'Blob', }); -InternalBlob.prototype.constructor = Blob; -ObjectSetPrototypeOf( - InternalBlob.prototype, - Blob.prototype); +function resolveObjectURL(url) { + url = `${url}`; + try { + const parsed = new lazyURL(url); + + const split = StringPrototypeSplit(parsed.pathname, ':'); + + if (split.length !== 2) + return; + + const { + 0: base, + 1: id, + } = split; + + if (base !== 'nodedata') + return; + + const ret = getDataObject(id); + + if (ret === undefined) + return; + + const { + 0: handle, + 1: length, + 2: type, + } = ret; + + if (handle !== undefined) + return createBlob(handle, length, type); + } catch { + // If there's an error, it's ignored and nothing is returned + } +} module.exports = { Blob, - InternalBlob, + ClonedBlob, + createBlob, isBlob, + kHandle, + resolveObjectURL, }; diff --git a/lib/internal/bootstrap/switches/is_main_thread.js b/lib/internal/bootstrap/switches/is_main_thread.js index 08623898edafac..1885f79ffec09e 100644 --- a/lib/internal/bootstrap/switches/is_main_thread.js +++ b/lib/internal/bootstrap/switches/is_main_thread.js @@ -100,6 +100,7 @@ function createWritableStdioStream(fd) { function dummyDestroy(err, cb) { cb(err); + this._undestroy(); // We need to emit 'close' anyway so that the closing // of the stream is observable. We just make sure we diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 7ff0832538f1e7..d46a5ce03f09c6 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -366,11 +366,8 @@ ChildProcess.prototype.spawn = function(options) { // Let child process know about opened IPC channel if (options.envPairs === undefined) options.envPairs = []; - else if (!ArrayIsArray(options.envPairs)) { - throw new ERR_INVALID_ARG_TYPE('options.envPairs', - 'Array', - options.envPairs); - } + else + validateArray(options.envPairs, 'options.envPairs'); ArrayPrototypePush(options.envPairs, `NODE_CHANNEL_FD=${ipcFd}`); ArrayPrototypePush(options.envPairs, diff --git a/lib/internal/crypto/keys.js b/lib/internal/crypto/keys.js index 27e28942fdaa8a..1127217d6b9dee 100644 --- a/lib/internal/crypto/keys.js +++ b/lib/internal/crypto/keys.js @@ -34,11 +34,11 @@ const { codes: { ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, + ERR_CRYPTO_INVALID_JWK, + ERR_ILLEGAL_CONSTRUCTOR, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_OUT_OF_RANGE, - ERR_OPERATION_FAILED, - ERR_CRYPTO_INVALID_JWK, } } = require('internal/errors'); @@ -631,7 +631,7 @@ function isKeyObject(obj) { // would be fantastic if we could find a way of making those interop. class CryptoKey extends JSTransferable { constructor() { - throw new ERR_OPERATION_FAILED('Illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } [kInspect](depth, options) { diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 0dcdc28a6c2f63..7cb32ec702767d 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -64,8 +64,11 @@ const { const { getRandomValues, + randomUUID: _randomUUID, } = require('internal/crypto/random'); +const randomUUID = () => _randomUUID(); + async function generateKey( algorithm, extractable, @@ -705,6 +708,12 @@ ObjectDefineProperties( writable: true, value: getRandomValues, }, + randomUUID: { + enumerable: true, + configurable: true, + writable: true, + value: randomUUID, + }, CryptoKey: { enumerable: true, configurable: true, @@ -795,4 +804,8 @@ ObjectDefineProperties( } }); -module.exports = crypto; +module.exports = { + Crypto, + SubtleCrypto, + crypto, +}; diff --git a/lib/internal/debugger/inspect_client.js b/lib/internal/debugger/inspect_client.js index 419b984cc9f473..5c72304ba285c3 100644 --- a/lib/internal/debugger/inspect_client.js +++ b/lib/internal/debugger/inspect_client.js @@ -40,8 +40,8 @@ const kMaskingKeyWidthInBytes = 4; // https://tools.ietf.org/html/rfc6455#section-1.3 const WEBSOCKET_HANDSHAKE_GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; -function unpackError({ code, message, data }) { - const err = new ERR_DEBUGGER_ERROR(`${message} - ${data}`); +function unpackError({ code, message }) { + const err = new ERR_DEBUGGER_ERROR(`${message}`); err.code = code; ErrorCaptureStackTrace(err, unpackError); return err; diff --git a/lib/internal/debugger/inspect_repl.js b/lib/internal/debugger/inspect_repl.js index a93a8dfecf2720..401887cbda5c74 100644 --- a/lib/internal/debugger/inspect_repl.js +++ b/lib/internal/debugger/inspect_repl.js @@ -325,6 +325,7 @@ function createRepl(inspector) { const history = { control: [], debug: [] }; const watchedExpressions = []; const knownBreakpoints = []; + let heapSnapshotPromise = null; let pauseOnExceptionState = 'none'; let lastCommand; @@ -961,7 +962,13 @@ function createRepl(inspector) { }, takeHeapSnapshot(filename = 'node.heapsnapshot') { - return new Promise((resolve, reject) => { + if (heapSnapshotPromise) { + print( + 'Cannot take heap snapshot because another snapshot is in progress.' + ); + return heapSnapshotPromise; + } + heapSnapshotPromise = new Promise((resolve, reject) => { const absoluteFile = Path.resolve(filename); const writer = FS.createWriteStream(absoluteFile); let sizeWritten = 0; @@ -983,6 +990,7 @@ function createRepl(inspector) { writer.end(() => { teardown(); print(`Wrote snapshot: ${absoluteFile}`); + heapSnapshotPromise = null; resolve(); }); } @@ -1006,6 +1014,7 @@ function createRepl(inspector) { HeapProfiler.takeHeapSnapshot({ reportProgress: true }), onResolve, onReject); }); + return heapSnapshotPromise; }, get watchers() { diff --git a/lib/internal/dns/promises.js b/lib/internal/dns/promises.js index 035e7f354efc7e..e32b6a1dcd9d19 100644 --- a/lib/internal/dns/promises.js +++ b/lib/internal/dns/promises.js @@ -12,6 +12,7 @@ const { Resolver: CallbackResolver, validateHints, validateTimeout, + validateTries, emitInvalidHostnameWarning, getDefaultVerbatim, } = require('internal/dns/utils'); @@ -216,7 +217,8 @@ const resolveMap = ObjectCreate(null); class Resolver { constructor(options = undefined) { const timeout = validateTimeout(options); - this._handle = new ChannelWrap(timeout); + const tries = validateTries(options); + this._handle = new ChannelWrap(timeout, tries); } } diff --git a/lib/internal/dns/utils.js b/lib/internal/dns/utils.js index 4f5cdf1104c243..f15f8c7a779ce1 100644 --- a/lib/internal/dns/utils.js +++ b/lib/internal/dns/utils.js @@ -43,11 +43,18 @@ function validateTimeout(options) { return timeout; } +function validateTries(options) { + const { tries = 4 } = { ...options }; + validateInt32(tries, 'options.tries', 1, 2 ** 31 - 1); + return tries; +} + // Resolver instances correspond 1:1 to c-ares channels. class Resolver { constructor(options = undefined) { const timeout = validateTimeout(options); - this._handle = new ChannelWrap(timeout); + const tries = validateTries(options); + this._handle = new ChannelWrap(timeout, tries); } cancel() { @@ -209,6 +216,7 @@ module.exports = { setDefaultResolver, validateHints, validateTimeout, + validateTries, Resolver, emitInvalidHostnameWarning, getDefaultVerbatim, diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index f6e52238a1270c..2cdd453b15ba91 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -39,7 +39,10 @@ const { isUint8Array } = require('internal/util/types'); -const { validateString } = require('internal/validators'); +const { + validateString, + validateObject, +} = require('internal/validators'); const { encodeInto, @@ -63,12 +66,6 @@ function validateDecoder(obj) { throw new ERR_INVALID_THIS('TextDecoder'); } -function validateArgument(prop, expected, propName, expectedName) { - // eslint-disable-next-line valid-typeof - if (typeof prop !== expected) - throw new ERR_INVALID_ARG_TYPE(propName, expectedName, prop); -} - const CONVERTER_FLAGS_FLUSH = 0x1; const CONVERTER_FLAGS_FATAL = 0x2; const CONVERTER_FLAGS_IGNORE_BOM = 0x4; @@ -381,7 +378,11 @@ function makeTextDecoderICU() { class TextDecoder { constructor(encoding = 'utf-8', options = {}) { encoding = `${encoding}`; - validateArgument(options, 'object', 'options', 'Object'); + validateObject(options, 'options', { + nullable: true, + allowArray: true, + allowFunction: true, + }); const enc = getEncodingFromLabel(encoding); if (enc === undefined) @@ -413,7 +414,11 @@ function makeTextDecoderICU() { ['ArrayBuffer', 'ArrayBufferView'], input); } - validateArgument(options, 'object', 'options', 'Object'); + validateObject(options, 'options', { + nullable: true, + allowArray: true, + allowFunction: true, + }); let flags = 0; if (options !== null) @@ -447,7 +452,11 @@ function makeTextDecoderJS() { class TextDecoder { constructor(encoding = 'utf-8', options = {}) { encoding = `${encoding}`; - validateArgument(options, 'object', 'options', 'Object'); + validateObject(options, 'options', { + nullable: true, + allowArray: true, + allowFunction: true, + }); const enc = getEncodingFromLabel(encoding); if (enc === undefined || !hasConverter(enc)) @@ -481,7 +490,11 @@ function makeTextDecoderJS() { ['ArrayBuffer', 'ArrayBufferView'], input); } - validateArgument(options, 'object', 'options', 'Object'); + validateObject(options, 'options', { + nullable: true, + allowArray: true, + allowFunction: true, + }); if (this[kFlags] & CONVERTER_FLAGS_FLUSH) { this[kBOMSeen] = false; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index b3953cbeb9436c..b9f7b893bbbf27 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -961,6 +961,17 @@ E('ERR_FEATURE_UNAVAILABLE_ON_PLATFORM', 'The feature %s is unavailable on the current platform' + ', which is being used to run Node.js', TypeError); +E('ERR_FS_CP_DIR_TO_NON_DIR', + 'Cannot overwrite directory with non-directory', SystemError); +E('ERR_FS_CP_EEXIST', 'Target already exists', SystemError); +E('ERR_FS_CP_EINVAL', 'Invalid src or dest', SystemError); +E('ERR_FS_CP_FIFO_PIPE', 'Cannot copy a FIFO pipe', SystemError); +E('ERR_FS_CP_NON_DIR_TO_DIR', + 'Cannot overwrite non-directory with directory', SystemError); +E('ERR_FS_CP_SOCKET', 'Cannot copy a socket file', SystemError); +E('ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY', + 'Cannot overwrite symlink in subdirectory of self', SystemError); +E('ERR_FS_CP_UNKNOWN', 'Cannot copy an unknown file type', SystemError); E('ERR_FS_EISDIR', 'Path is a directory', SystemError); E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than 2 GB', RangeError); E('ERR_FS_INVALID_SYMLINK_TYPE', @@ -1264,8 +1275,6 @@ E('ERR_INVALID_PACKAGE_TARGET', pkgPath}package.json${base ? ` imported from ${base}` : ''}${relError ? '; targets must start with "./"' : ''}`; }, Error); -E('ERR_INVALID_PERFORMANCE_MARK', - 'The "%s" performance mark has not been set', Error); E('ERR_INVALID_PROTOCOL', 'Protocol "%s" not supported. Expected "%s"', TypeError); diff --git a/lib/internal/fs/cp/cp-sync.js b/lib/internal/fs/cp/cp-sync.js new file mode 100644 index 00000000000000..ca2102aeb5ada8 --- /dev/null +++ b/lib/internal/fs/cp/cp-sync.js @@ -0,0 +1,331 @@ +'use strict'; + +// This file is a modified version of the fs-extra's copySync method. + +const { areIdentical, isSrcSubdir } = require('internal/fs/cp/cp'); +const { codes } = require('internal/errors'); +const { + os: { + errno: { + EEXIST, + EISDIR, + EINVAL, + ENOTDIR, + } + } +} = internalBinding('constants'); +const { + ERR_FS_CP_DIR_TO_NON_DIR, + ERR_FS_CP_EEXIST, + ERR_FS_CP_EINVAL, + ERR_FS_CP_FIFO_PIPE, + ERR_FS_CP_NON_DIR_TO_DIR, + ERR_FS_CP_SOCKET, + ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY, + ERR_FS_CP_UNKNOWN, + ERR_FS_EISDIR, + ERR_INVALID_RETURN_VALUE, +} = codes; +const fs = require('fs'); +const { + chmodSync, + copyFileSync, + existsSync, + lstatSync, + mkdirSync, + readdirSync, + readlinkSync, + statSync, + symlinkSync, + unlinkSync, + utimesSync, +} = fs; +const path = require('path'); +const { + dirname, + isAbsolute, + join, + parse, + resolve, +} = path; +const { isPromise } = require('util/types'); + +function cpSyncFn(src, dest, opts) { + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + const warning = 'Using the preserveTimestamps option in 32-bit ' + + 'node is not recommended'; + process.emitWarning(warning, 'TimestampPrecisionWarning'); + } + const { srcStat, destStat } = checkPathsSync(src, dest, opts); + checkParentPathsSync(src, srcStat, dest); + return handleFilterAndCopy(destStat, src, dest, opts); +} + +function checkPathsSync(src, dest, opts) { + const { srcStat, destStat } = getStatsSync(src, dest, opts); + + if (destStat) { + if (areIdentical(srcStat, destStat)) { + throw new ERR_FS_CP_EINVAL({ + message: 'src and dest cannot be the same', + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + throw new ERR_FS_CP_DIR_TO_NON_DIR({ + message: `cannot overwrite directory ${src} ` + + `with non-directory ${dest}`, + path: dest, + syscall: 'cp', + errno: EISDIR, + }); + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + throw new ERR_FS_CP_NON_DIR_TO_DIR({ + message: `cannot overwrite non-directory ${src} ` + + `with directory ${dest}`, + path: dest, + syscall: 'cp', + errno: ENOTDIR, + }); + } + } + + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${src} to a subdirectory of self ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return { srcStat, destStat }; +} + +function getStatsSync(src, dest, opts) { + let destStat; + const statFunc = opts.dereference ? + (file) => statSync(file, { bigint: true }) : + (file) => lstatSync(file, { bigint: true }); + const srcStat = statFunc(src); + try { + destStat = statFunc(dest); + } catch (err) { + if (err.code === 'ENOENT') return { srcStat, destStat: null }; + throw err; + } + return { srcStat, destStat }; +} + +function checkParentPathsSync(src, srcStat, dest) { + const srcParent = resolve(dirname(src)); + const destParent = resolve(dirname(dest)); + if (destParent === srcParent || destParent === parse(destParent).root) return; + let destStat; + try { + destStat = statSync(destParent, { bigint: true }); + } catch (err) { + if (err.code === 'ENOENT') return; + throw err; + } + if (areIdentical(srcStat, destStat)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${src} to a subdirectory of self ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return checkParentPathsSync(src, srcStat, destParent); +} + +function handleFilterAndCopy(destStat, src, dest, opts) { + if (opts.filter) { + const shouldCopy = opts.filter(src, dest); + if (isPromise(shouldCopy)) { + throw new ERR_INVALID_RETURN_VALUE('boolean', 'filter', shouldCopy); + } + if (!shouldCopy) return; + } + const destParent = dirname(dest); + if (!existsSync(destParent)) mkdirSync(destParent, { recursive: true }); + return getStats(destStat, src, dest, opts); +} + +function startCopy(destStat, src, dest, opts) { + if (opts.filter && !opts.filter(src, dest)) return; + return getStats(destStat, src, dest, opts); +} + +function getStats(destStat, src, dest, opts) { + const statSyncFn = opts.dereference ? statSync : lstatSync; + const srcStat = statSyncFn(src); + + if (srcStat.isDirectory() && opts.recursive) { + return onDir(srcStat, destStat, src, dest, opts); + } else if (srcStat.isDirectory()) { + throw new ERR_FS_EISDIR({ + message: `${src} is a directory (not copied)`, + path: src, + syscall: 'cp', + errno: EINVAL, + }); + } else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) { + return onFile(srcStat, destStat, src, dest, opts); + } else if (srcStat.isSymbolicLink()) { + return onLink(destStat, src, dest); + } else if (srcStat.isSocket()) { + throw new ERR_FS_CP_SOCKET({ + message: `cannot copy a socket file: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } else if (srcStat.isFIFO()) { + throw new ERR_FS_CP_FIFO_PIPE({ + message: `cannot copy a FIFO pipe: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + throw new ERR_FS_CP_UNKNOWN({ + message: `cannot copy an unknown file type: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); +} + +function onFile(srcStat, destStat, src, dest, opts) { + if (!destStat) return copyFile(srcStat, src, dest, opts); + return mayCopyFile(srcStat, src, dest, opts); +} + +function mayCopyFile(srcStat, src, dest, opts) { + if (opts.force) { + unlinkSync(dest); + return copyFile(srcStat, src, dest, opts); + } else if (opts.errorOnExist) { + throw new ERR_FS_CP_EEXIST({ + message: `${dest} already exists`, + path: dest, + syscall: 'cp', + errno: EEXIST, + }); + } +} + +function copyFile(srcStat, src, dest, opts) { + copyFileSync(src, dest); + if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); + return setDestMode(dest, srcStat.mode); +} + +function handleTimestamps(srcMode, src, dest) { + // Make sure the file is writable before setting the timestamp + // otherwise open fails with EPERM when invoked with 'r+' + // (through utimes call) + if (fileIsNotWritable(srcMode)) makeFileWritable(dest, srcMode); + return setDestTimestamps(src, dest); +} + +function fileIsNotWritable(srcMode) { + return (srcMode & 0o200) === 0; +} + +function makeFileWritable(dest, srcMode) { + return setDestMode(dest, srcMode | 0o200); +} + +function setDestMode(dest, srcMode) { + return chmodSync(dest, srcMode); +} + +function setDestTimestamps(src, dest) { + // The initial srcStat.atime cannot be trusted + // because it is modified by the read(2) system call + // (See https://nodejs.org/api/fs.html#fs_stat_time_values) + const updatedSrcStat = statSync(src); + return utimesSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime); +} + +function onDir(srcStat, destStat, src, dest, opts) { + if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts); + return copyDir(src, dest, opts); +} + +function mkDirAndCopy(srcMode, src, dest, opts) { + mkdirSync(dest); + copyDir(src, dest, opts); + return setDestMode(dest, srcMode); +} + +function copyDir(src, dest, opts) { + readdirSync(src).forEach((item) => copyDirItem(item, src, dest, opts)); +} + +function copyDirItem(item, src, dest, opts) { + const srcItem = join(src, item); + const destItem = join(dest, item); + const { destStat } = checkPathsSync(srcItem, destItem, opts); + return startCopy(destStat, srcItem, destItem, opts); +} + +function onLink(destStat, src, dest) { + let resolvedSrc = readlinkSync(src); + if (!isAbsolute(resolvedSrc)) { + resolvedSrc = resolve(dirname(src), resolvedSrc); + } + if (!destStat) { + return symlinkSync(resolvedSrc, dest); + } + let resolvedDest; + try { + resolvedDest = readlinkSync(dest); + } catch (err) { + // Dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') { + return symlinkSync(resolvedSrc, dest); + } + throw err; + } + if (!isAbsolute(resolvedDest)) { + resolvedDest = resolve(dirname(dest), resolvedDest); + } + if (isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${resolvedSrc} to a subdirectory of self ` + + `${resolvedDest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + // Prevent copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + if (statSync(dest).isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({ + message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return copyLink(resolvedSrc, dest); +} + +function copyLink(resolvedSrc, dest) { + unlinkSync(dest); + return symlinkSync(resolvedSrc, dest); +} + +module.exports = { cpSyncFn }; diff --git a/lib/internal/fs/cp/cp.js b/lib/internal/fs/cp/cp.js new file mode 100644 index 00000000000000..9ee661be68d1e2 --- /dev/null +++ b/lib/internal/fs/cp/cp.js @@ -0,0 +1,384 @@ +'use strict'; + +// This file is a modified version of the fs-extra's copy method. + +const { + ArrayPrototypeEvery, + ArrayPrototypeFilter, + Boolean, + PromiseAll, + PromisePrototypeCatch, + PromisePrototypeThen, + PromiseReject, + SafeArrayIterator, + StringPrototypeSplit, +} = primordials; +const { + codes: { + ERR_FS_CP_DIR_TO_NON_DIR, + ERR_FS_CP_EEXIST, + ERR_FS_CP_EINVAL, + ERR_FS_CP_FIFO_PIPE, + ERR_FS_CP_NON_DIR_TO_DIR, + ERR_FS_CP_SOCKET, + ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY, + ERR_FS_CP_UNKNOWN, + ERR_FS_EISDIR, + }, +} = require('internal/errors'); +const { + os: { + errno: { + EEXIST, + EISDIR, + EINVAL, + ENOTDIR, + } + } +} = internalBinding('constants'); +const { + chmod, + copyFile, + lstat, + mkdir, + readdir, + readlink, + stat, + symlink, + unlink, + utimes, +} = require('fs/promises'); +const { + dirname, + isAbsolute, + join, + parse, + resolve, + sep, +} = require('path'); + +async function cpFn(src, dest, opts) { + // Warn about using preserveTimestamps on 32-bit node + if (opts.preserveTimestamps && process.arch === 'ia32') { + const warning = 'Using the preserveTimestamps option in 32-bit ' + + 'node is not recommended'; + process.emitWarning(warning, 'TimestampPrecisionWarning'); + } + const stats = await checkPaths(src, dest, opts); + const { srcStat, destStat } = stats; + await checkParentPaths(src, srcStat, dest); + if (opts.filter) { + return handleFilter(checkParentDir, destStat, src, dest, opts); + } + return checkParentDir(destStat, src, dest, opts); +} + +async function checkPaths(src, dest, opts) { + const { 0: srcStat, 1: destStat } = await getStats(src, dest, opts); + if (destStat) { + if (areIdentical(srcStat, destStat)) { + throw new ERR_FS_CP_EINVAL({ + message: 'src and dest cannot be the same', + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + if (srcStat.isDirectory() && !destStat.isDirectory()) { + throw new ERR_FS_CP_DIR_TO_NON_DIR({ + message: `cannot overwrite directory ${src} ` + + `with non-directory ${dest}`, + path: dest, + syscall: 'cp', + errno: EISDIR, + }); + } + if (!srcStat.isDirectory() && destStat.isDirectory()) { + throw new ERR_FS_CP_NON_DIR_TO_DIR({ + message: `cannot overwrite non-directory ${src} ` + + `with directory ${dest}`, + path: dest, + syscall: 'cp', + errno: ENOTDIR, + }); + } + } + + if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${src} to a subdirectory of self ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return { srcStat, destStat }; +} + +function areIdentical(srcStat, destStat) { + return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && + destStat.dev === srcStat.dev; +} + +function getStats(src, dest, opts) { + const statFunc = opts.dereference ? + (file) => stat(file, { bigint: true }) : + (file) => lstat(file, { bigint: true }); + return PromiseAll(new SafeArrayIterator([ + statFunc(src), + PromisePrototypeCatch(statFunc(dest), (err) => { + if (err.code === 'ENOENT') return null; + throw err; + }), + ])); +} + +async function checkParentDir(destStat, src, dest, opts) { + const destParent = dirname(dest); + const dirExists = await pathExists(destParent); + if (dirExists) return getStatsForCopy(destStat, src, dest, opts); + await mkdir(destParent, { recursive: true }); + return getStatsForCopy(destStat, src, dest, opts); +} + +function pathExists(dest) { + return PromisePrototypeThen( + stat(dest), + () => true, + (err) => (err.code === 'ENOENT' ? false : PromiseReject(err))); +} + +// Recursively check if dest parent is a subdirectory of src. +// It works for all file types including symlinks since it +// checks the src and dest inodes. It starts from the deepest +// parent and stops once it reaches the src parent or the root path. +async function checkParentPaths(src, srcStat, dest) { + const srcParent = resolve(dirname(src)); + const destParent = resolve(dirname(dest)); + if (destParent === srcParent || destParent === parse(destParent).root) { + return; + } + let destStat; + try { + destStat = await stat(destParent, { bigint: true }); + } catch (err) { + if (err.code === 'ENOENT') return; + throw err; + } + if (areIdentical(srcStat, destStat)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${src} to a subdirectory of self ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return checkParentPaths(src, srcStat, destParent); +} + +const normalizePathToArray = (path) => + ArrayPrototypeFilter(StringPrototypeSplit(resolve(path), sep), Boolean); + +// Return true if dest is a subdir of src, otherwise false. +// It only checks the path strings. +function isSrcSubdir(src, dest) { + const srcArr = normalizePathToArray(src); + const destArr = normalizePathToArray(dest); + return ArrayPrototypeEvery(srcArr, (cur, i) => destArr[i] === cur); +} + +async function handleFilter(onInclude, destStat, src, dest, opts, cb) { + const include = await opts.filter(src, dest); + if (include) return onInclude(destStat, src, dest, opts, cb); +} + +function startCopy(destStat, src, dest, opts) { + if (opts.filter) { + return handleFilter(getStatsForCopy, destStat, src, dest, opts); + } + return getStatsForCopy(destStat, src, dest, opts); +} + +async function getStatsForCopy(destStat, src, dest, opts) { + const statFn = opts.dereference ? stat : lstat; + const srcStat = await statFn(src); + if (srcStat.isDirectory() && opts.recursive) { + return onDir(srcStat, destStat, src, dest, opts); + } else if (srcStat.isDirectory()) { + throw new ERR_FS_EISDIR({ + message: `${src} is a directory (not copied)`, + path: src, + syscall: 'cp', + errno: EINVAL, + }); + } else if (srcStat.isFile() || + srcStat.isCharacterDevice() || + srcStat.isBlockDevice()) { + return onFile(srcStat, destStat, src, dest, opts); + } else if (srcStat.isSymbolicLink()) { + return onLink(destStat, src, dest); + } else if (srcStat.isSocket()) { + throw new ERR_FS_CP_SOCKET({ + message: `cannot copy a socket file: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } else if (srcStat.isFIFO()) { + throw new ERR_FS_CP_FIFO_PIPE({ + message: `cannot copy a FIFO pipe: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + throw new ERR_FS_CP_UNKNOWN({ + message: `cannot copy an unknown file type: ${dest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); +} + +function onFile(srcStat, destStat, src, dest, opts) { + if (!destStat) return _copyFile(srcStat, src, dest, opts); + return mayCopyFile(srcStat, src, dest, opts); +} + +async function mayCopyFile(srcStat, src, dest, opts) { + if (opts.force) { + await unlink(dest); + return _copyFile(srcStat, src, dest, opts); + } else if (opts.errorOnExist) { + throw new ERR_FS_CP_EEXIST({ + message: `${dest} already exists`, + path: dest, + syscall: 'cp', + errno: EEXIST, + }); + } +} + +async function _copyFile(srcStat, src, dest, opts) { + await copyFile(src, dest); + if (opts.preserveTimestamps) { + return handleTimestampsAndMode(srcStat.mode, src, dest); + } + return setDestMode(dest, srcStat.mode); +} + +async function handleTimestampsAndMode(srcMode, src, dest) { + // Make sure the file is writable before setting the timestamp + // otherwise open fails with EPERM when invoked with 'r+' + // (through utimes call) + if (fileIsNotWritable(srcMode)) { + await makeFileWritable(dest, srcMode); + return setDestTimestampsAndMode(srcMode, src, dest); + } + return setDestTimestampsAndMode(srcMode, src, dest); +} + +function fileIsNotWritable(srcMode) { + return (srcMode & 0o200) === 0; +} + +function makeFileWritable(dest, srcMode) { + return setDestMode(dest, srcMode | 0o200); +} + +async function setDestTimestampsAndMode(srcMode, src, dest) { + await setDestTimestamps(src, dest); + return setDestMode(dest, srcMode); +} + +function setDestMode(dest, srcMode) { + return chmod(dest, srcMode); +} + +async function setDestTimestamps(src, dest) { + // The initial srcStat.atime cannot be trusted + // because it is modified by the read(2) system call + // (See https://nodejs.org/api/fs.html#fs_stat_time_values) + const updatedSrcStat = await stat(src); + return utimes(dest, updatedSrcStat.atime, updatedSrcStat.mtime); +} + +function onDir(srcStat, destStat, src, dest, opts) { + if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts); + return copyDir(src, dest, opts); +} + +async function mkDirAndCopy(srcMode, src, dest, opts) { + await mkdir(dest); + await copyDir(src, dest, opts); + return setDestMode(dest, srcMode); +} + +async function copyDir(src, dest, opts) { + const dir = await readdir(src); + for (let i = 0; i < dir.length; i++) { + const item = dir[i]; + const srcItem = join(src, item); + const destItem = join(dest, item); + const { destStat } = await checkPaths(srcItem, destItem, opts); + await startCopy(destStat, srcItem, destItem, opts); + } +} + +async function onLink(destStat, src, dest) { + let resolvedSrc = await readlink(src); + if (!isAbsolute(resolvedSrc)) { + resolvedSrc = resolve(dirname(src), resolvedSrc); + } + if (!destStat) { + return symlink(resolvedSrc, dest); + } + let resolvedDest; + try { + resolvedDest = await readlink(dest); + } catch (err) { + // Dest exists and is a regular file or directory, + // Windows may throw UNKNOWN error. If dest already exists, + // fs throws error anyway, so no need to guard against it here. + if (err.code === 'EINVAL' || err.code === 'UNKNOWN') { + return symlink(resolvedSrc, dest); + } + throw err; + } + if (!isAbsolute(resolvedDest)) { + resolvedDest = resolve(dirname(dest), resolvedDest); + } + if (isSrcSubdir(resolvedSrc, resolvedDest)) { + throw new ERR_FS_CP_EINVAL({ + message: `cannot copy ${resolvedSrc} to a subdirectory of self ` + + `${resolvedDest}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + // Do not copy if src is a subdir of dest since unlinking + // dest in this case would result in removing src contents + // and therefore a broken symlink would be created. + const srcStat = await stat(src); + if (srcStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) { + throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({ + message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`, + path: dest, + syscall: 'cp', + errno: EINVAL, + }); + } + return copyLink(resolvedSrc, dest); +} + +async function copyLink(resolvedSrc, dest) { + await unlink(dest); + return symlink(resolvedSrc, dest); +} + +module.exports = { + areIdentical, + cpFn, + isSrcSubdir, +}; diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 6007e7384cbca3..eaabd031f06784 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -56,12 +56,13 @@ const { stringToSymlinkType, toUnixTimestamp, validateBufferArray, + validateCpOptions, validateOffsetLengthRead, validateOffsetLengthWrite, validateRmOptions, validateRmdirOptions, validateStringAfterArrayBufferView, - warnOnNonPortableTemplate + warnOnNonPortableTemplate, } = require('internal/fs/utils'); const { opendir } = require('internal/fs/dir'); const { @@ -97,6 +98,11 @@ const { const getDirectoryEntriesPromise = promisify(getDirents); const validateRmOptionsPromise = promisify(validateRmOptions); +let cpPromises; +function lazyLoadCpPromises() { + return cpPromises ??= require('internal/fs/cp/cp').cpFn; +} + class FileHandle extends EventEmitterMixin(JSTransferable) { /** * @param {InternalFSBinding.FileHandle | undefined} filehandle @@ -381,6 +387,13 @@ async function access(path, mode = F_OK) { kUsePromises); } +async function cp(src, dest, options) { + options = validateCpOptions(options); + src = pathModule.toNamespacedPath(getValidatedPath(src, 'src')); + dest = pathModule.toNamespacedPath(getValidatedPath(dest, 'dest')); + return lazyLoadCpPromises()(src, dest, options); +} + async function copyFile(src, dest, mode) { src = getValidatedPath(src, 'src'); dest = getValidatedPath(dest, 'dest'); @@ -747,6 +760,7 @@ module.exports = { exports: { access, copyFile, + cp, open, opendir: promisify(opendir), rename, diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 322b1519ef2807..b0aeb8185e9aa8 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -47,6 +47,7 @@ const { toPathIfFileURL } = require('internal/url'); const { validateAbortSignal, validateBoolean, + validateFunction, validateInt32, validateInteger, validateObject, @@ -716,6 +717,15 @@ function warnOnNonPortableTemplate(template) { } } +const defaultCpOptions = { + dereference: false, + errorOnExist: false, + filter: undefined, + force: true, + preserveTimestamps: false, + recursive: false, +}; + const defaultRmOptions = { recursive: false, force: false, @@ -729,6 +739,22 @@ const defaultRmdirOptions = { recursive: false, }; +const validateCpOptions = hideStackFrames((options) => { + if (options === undefined) + return { ...defaultCpOptions }; + validateObject(options, 'options'); + options = { ...defaultCpOptions, ...options }; + validateBoolean(options.dereference, 'options.dereference'); + validateBoolean(options.errorOnExist, 'options.errorOnExist'); + validateBoolean(options.force, 'options.force'); + validateBoolean(options.preserveTimestamps, 'options.preserveTimestamps'); + validateBoolean(options.recursive, 'options.recursive'); + if (options.filter !== undefined) { + validateFunction(options.filter, 'options.filter'); + } + return options; +}); + const validateRmOptions = hideStackFrames((path, options, expectDir, cb) => { options = validateRmdirOptions(options, defaultRmOptions); validateBoolean(options.force, 'options.force'); @@ -902,6 +928,7 @@ module.exports = { Stats, toUnixTimestamp, validateBufferArray, + validateCpOptions, validateOffsetLengthRead, validateOffsetLengthWrite, validatePath, diff --git a/lib/internal/histogram.js b/lib/internal/histogram.js index 2df321300fb87e..f437bfd4d791ac 100644 --- a/lib/internal/histogram.js +++ b/lib/internal/histogram.js @@ -7,7 +7,6 @@ const { ObjectSetPrototypeOf, SafeMap, Symbol, - TypeError, } = primordials; const { @@ -22,6 +21,7 @@ const { inspect } = require('util'); const { codes: { + ERR_ILLEGAL_CONSTRUCTOR, ERR_INVALID_ARG_VALUE, ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE, @@ -130,8 +130,7 @@ class Histogram extends JSTransferable { class RecordableHistogram extends Histogram { constructor() { - // eslint-disable-next-line no-restricted-syntax - throw new TypeError('illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } record(val) { diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js index faad988e820ffa..bd902412564ceb 100644 --- a/lib/internal/js_stream_socket.js +++ b/lib/internal/js_stream_socket.js @@ -22,15 +22,44 @@ const kCurrentWriteRequest = Symbol('kCurrentWriteRequest'); const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest'); const kPendingShutdownRequest = Symbol('kPendingShutdownRequest'); -function isClosing() { return this[owner_symbol].isClosing(); } +function checkReusedHandle(self) { + let socket = self[owner_symbol]; -function onreadstart() { return this[owner_symbol].readStart(); } + if (socket.constructor.name === 'ReusedHandle') + socket = socket.handle; -function onreadstop() { return this[owner_symbol].readStop(); } + return socket; +} + +function isClosing() { + const socket = checkReusedHandle(this); + + return socket.isClosing(); +} + +function onreadstart() { + const socket = checkReusedHandle(this); + + return socket.readStart(); +} -function onshutdown(req) { return this[owner_symbol].doShutdown(req); } +function onreadstop() { + const socket = checkReusedHandle(this); -function onwrite(req, bufs) { return this[owner_symbol].doWrite(req, bufs); } + return socket.readStop(); +} + +function onshutdown(req) { + const socket = checkReusedHandle(this); + + return socket.doShutdown(req); +} + +function onwrite(req, bufs) { + const socket = checkReusedHandle(this); + + return socket.doWrite(req, bufs); +} /* This class serves as a wrapper for when the C++ side of Node wants access * to a standard JS stream. For example, TLS or HTTP do not operate on network diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 8b6f23bb485d8b..0a0da107682469 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -59,7 +59,26 @@ const userConditions = getOptionValue('--conditions'); const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import', ...userConditions]); const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); +/** + * @typedef {string | string[] | Record} Exports + * @typedef {'module' | 'commonjs'} PackageType + * @typedef {{ + * exports?: ExportConfig; + * name?: string; + * main?: string; + * type?: PackageType; + * }} PackageConfig + */ + const emittedPackageWarnings = new SafeSet(); + +/** + * @param {string} match + * @param {URL} pjsonUrl + * @param {boolean} isExports + * @param {string | URL | undefined} base + * @returns {void} + */ function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { const pjsonPath = fileURLToPath(pjsonUrl); @@ -76,6 +95,13 @@ function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { ); } +/** + * @param {URL} url + * @param {URL} packageJSONUrl + * @param {string | URL | undefined} base + * @param {string} main + * @returns + */ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) { const { format } = defaultGetFormat(url); if (format !== 'module') @@ -104,6 +130,10 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) { ); } +/** + * @param {string[]} [conditions] + * @returns {Set} + */ function getConditionsSet(conditions) { if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { if (!ArrayIsArray(conditions)) { @@ -118,9 +148,19 @@ function getConditionsSet(conditions) { const realpathCache = new SafeMap(); const packageJSONCache = new SafeMap(); /* string -> PackageConfig */ +/** + * @param {string | URL} path + * @returns {import('fs').Stats} + */ const tryStatSync = (path) => statSync(path, { throwIfNoEntry: false }) ?? new Stats(); +/** + * @param {string} path + * @param {string} specifier + * @param {string | URL | undefined} base + * @returns {PackageConfig} + */ function getPackageConfig(path, specifier, base) { const existing = packageJSONCache.get(path); if (existing !== undefined) { @@ -173,6 +213,10 @@ function getPackageConfig(path, specifier, base) { return packageConfig; } +/** + * @param {URL | string} resolved + * @returns {PackageConfig} + */ function getPackageScopeConfig(resolved) { let packageJSONUrl = new URL('./package.json', resolved); while (true) { @@ -205,12 +249,6 @@ function getPackageScopeConfig(resolved) { } /** - * Legacy CommonJS main resolution: - * 1. let M = pkg_url + (json main field) - * 2. TRY(M, M.js, M.json, M.node) - * 3. TRY(M/index.js, M/index.json, M/index.node) - * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) - * 5. NOT_FOUND * @param {string | URL} url * @returns {boolean} */ @@ -218,6 +256,18 @@ function fileExists(url) { return statSync(url, { throwIfNoEntry: false })?.isFile() ?? false; } +/** + * Legacy CommonJS main resolution: + * 1. let M = pkg_url + (json main field) + * 2. TRY(M, M.js, M.json, M.node) + * 3. TRY(M/index.js, M/index.json, M/index.node) + * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) + * 5. NOT_FOUND + * @param {URL} packageJSONUrl + * @param {PackageConfig} packageConfig + * @param {string | URL | undefined} base + * @returns {URL} + */ function legacyMainResolve(packageJSONUrl, packageConfig, base) { let guess; if (packageConfig.main !== undefined) { @@ -259,12 +309,21 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) { fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); } +/** + * @param {URL} search + * @returns {URL | undefined} + */ function resolveExtensionsWithTryExactName(search) { if (fileExists(search)) return search; return resolveExtensions(search); } const extensions = ['.js', '.json', '.node', '.mjs']; + +/** + * @param {URL} search + * @returns {URL | undefined} + */ function resolveExtensions(search) { for (let i = 0; i < extensions.length; i++) { const extension = extensions[i]; @@ -274,6 +333,10 @@ function resolveExtensions(search) { return undefined; } +/** + * @param {URL} search + * @returns {URL | undefined} + */ function resolveDirectoryEntry(search) { const dirPath = fileURLToPath(search); const pkgJsonPath = resolve(dirPath, 'package.json'); @@ -291,6 +354,11 @@ function resolveDirectoryEntry(search) { } const encodedSepRegEx = /%2F|%2C/i; +/** + * @param {URL} resolved + * @param {string | URL | undefined} base + * @returns {URL | undefined} + */ function finalizeResolution(resolved, base) { if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname)) throw new ERR_INVALID_MODULE_SPECIFIER( @@ -325,18 +393,35 @@ function finalizeResolution(resolved, base) { return resolved; } +/** + * @param {string} specifier + * @param {URL} packageJSONUrl + * @param {string | URL | undefined} base + */ function throwImportNotDefined(specifier, packageJSONUrl, base) { throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( specifier, packageJSONUrl && fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); } +/** + * @param {string} specifier + * @param {URL} packageJSONUrl + * @param {string | URL | undefined} base + */ function throwExportsNotFound(subpath, packageJSONUrl, base) { throw new ERR_PACKAGE_PATH_NOT_EXPORTED( fileURLToPath(new URL('.', packageJSONUrl)), subpath, base && fileURLToPath(base)); } +/** + * + * @param {string | URL} subpath + * @param {URL} packageJSONUrl + * @param {boolean} internal + * @param {string | URL | undefined} base + */ function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) { const reason = `request is not a valid subpath for the "${internal ? 'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}`; @@ -478,6 +563,13 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, base); } +/** + * + * @param {Exports} exports + * @param {URL} packageJSONUrl + * @param {string | URL | undefined} base + * @returns + */ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { if (typeof exports === 'string' || ArrayIsArray(exports)) return true; if (typeof exports !== 'object' || exports === null) return false; @@ -504,8 +596,8 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { /** * @param {URL} packageJSONUrl * @param {string} packageSubpath - * @param {object} packageConfig - * @param {string} base + * @param {PackageConfig} packageConfig + * @param {string | URL | undefined} base * @param {Set} conditions * @returns {URL} */ @@ -560,6 +652,12 @@ function packageExportsResolve( throwExportsNotFound(packageSubpath, packageJSONUrl, base); } +/** + * @param {string} name + * @param {string | URL | undefined} base + * @param {Set} conditions + * @returns + */ function packageImportsResolve(name, base, conditions) { if (name === '#' || StringPrototypeStartsWith(name, '#/')) { const reason = 'is not a valid internal imports specifier name'; @@ -615,11 +713,20 @@ function packageImportsResolve(name, base, conditions) { throwImportNotDefined(name, packageJSONUrl, base); } +/** + * @param {URL} url + * @returns {PackageType} + */ function getPackageType(url) { const packageConfig = getPackageScopeConfig(url); return packageConfig.type; } +/** + * @param {string} specifier + * @param {string | URL | undefined} base + * @returns {{ packageName: string, packageSubpath: string, isScoped: boolean }} + */ function parsePackageName(specifier, base) { let separatorIndex = StringPrototypeIndexOf(specifier, '/'); let validPackageName = true; @@ -659,7 +766,7 @@ function parsePackageName(specifier, base) { /** * @param {string} specifier - * @param {URL} base + * @param {string | URL | undefined} base * @param {Set} conditions * @returns {URL} */ @@ -712,6 +819,10 @@ function packageResolve(specifier, base, conditions) { throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); } +/** + * @param {string} specifier + * @returns {boolean} + */ function isBareSpecifier(specifier) { return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.'; } @@ -734,7 +845,7 @@ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { /** * @param {string} specifier - * @param {URL} base + * @param {string | URL | undefined} base * @param {Set} conditions * @returns {URL} */ diff --git a/lib/internal/perf/event_loop_delay.js b/lib/internal/perf/event_loop_delay.js index f90bb9e4de7d58..f5d0eb74d588e4 100644 --- a/lib/internal/perf/event_loop_delay.js +++ b/lib/internal/perf/event_loop_delay.js @@ -1,9 +1,14 @@ 'use strict'; const { Symbol, - TypeError, } = primordials; +const { + codes: { + ERR_ILLEGAL_CONSTRUCTOR, + } +} = require('internal/errors'); + const { ELDHistogram: _ELDHistogram, } = internalBinding('performance'); @@ -23,8 +28,7 @@ const kEnabled = Symbol('kEnabled'); class ELDHistogram extends Histogram { constructor(i) { if (!(i instanceof _ELDHistogram)) { - // eslint-disable-next-line no-restricted-syntax - throw new TypeError('illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } super(i); this[kEnabled] = false; diff --git a/lib/internal/perf/observe.js b/lib/internal/perf/observe.js index 8ec8512434510b..eadc617452e952 100644 --- a/lib/internal/perf/observe.js +++ b/lib/internal/perf/observe.js @@ -4,10 +4,13 @@ const { ArrayFrom, ArrayIsArray, ArrayPrototypeFilter, + ArrayPrototypeFlatMap, ArrayPrototypeIncludes, ArrayPrototypePush, + ArrayPrototypePushApply, ArrayPrototypeSlice, ArrayPrototypeSort, + Error, ObjectDefineProperties, ObjectFreeze, ObjectKeys, @@ -31,6 +34,7 @@ const { const { InternalPerformanceEntry, isPerformanceEntry, + kBufferNext, } = require('internal/perf/performance_entry'); const { @@ -49,6 +53,7 @@ const { const { customInspectSymbol: kInspect, deprecate, + lazyDOMException, } = require('internal/util'); const { @@ -83,6 +88,16 @@ const kSupportedEntryTypes = ObjectFreeze([ 'measure', ]); +// Performance timeline entry Buffers +const markEntryBuffer = createBuffer(); +const measureEntryBuffer = createBuffer(); +const kMaxPerformanceEntryBuffers = 1e6; +const kClearPerformanceEntryBuffers = ObjectFreeze({ + 'mark': 'performance.clearMarks', + 'measure': 'performance.clearMeasures', +}); +const kWarnedEntryTypes = new SafeMap(); + const kObservers = new SafeSet(); const kPending = new SafeSet(); let isPending = false; @@ -92,9 +107,10 @@ function queuePending() { isPending = true; setImmediate(() => { isPending = false; - for (const pending of kPending) - pending[kDispatch](); + const pendings = ArrayFrom(kPending.values()); kPending.clear(); + for (const pending of pendings) + pending[kDispatch](); }); } @@ -116,6 +132,7 @@ function maybeDecrementObserverCounts(entryTypes) { if (observerType === NODE_PERFORMANCE_ENTRY_TYPE_GC && observerCounts[observerType] === 0) { removeGarbageCollectionTracking(); + gcTrackingInstalled = false; } } } @@ -154,8 +171,13 @@ class PerformanceObserverEntryList { (entry) => entry.entryType === type); } - getEntriesByName(name) { + getEntriesByName(name, type) { name = `${name}`; + if (type != null /** not nullish */) { + return ArrayPrototypeFilter( + this[kBuffer], + (entry) => entry.name === name && entry.entryType === type); + } return ArrayPrototypeFilter( this[kBuffer], (entry) => entry.name === name); @@ -190,9 +212,15 @@ class PerformanceObserver { const { entryTypes, type, + buffered, } = { ...options }; if (entryTypes === undefined && type === undefined) throw new ERR_MISSING_ARGS('options.entryTypes', 'options.type'); + if (entryTypes != null && type != null) + throw new ERR_INVALID_ARG_VALUE('options.entryTypes', + entryTypes, + 'options.entryTypes can not set with ' + + 'options.type together'); switch (this[kType]) { case undefined: @@ -201,11 +229,15 @@ class PerformanceObserver { break; case kTypeSingle: if (entryTypes !== undefined) - throw new ERR_INVALID_ARG_VALUE('options.entryTypes', entryTypes); + throw lazyDOMException( + 'PerformanceObserver can not change to multiple observations', + 'InvalidModificationError'); break; case kTypeMultiple: if (type !== undefined) - throw new ERR_INVALID_ARG_VALUE('options.type', type); + throw lazyDOMException( + 'PerformanceObserver can not change to single observation', + 'InvalidModificationError'); break; } @@ -229,6 +261,13 @@ class PerformanceObserver { return; this[kEntryTypes].add(type); maybeIncrementObserverCount(type); + if (buffered) { + const entries = filterBufferMapByNameAndType(undefined, type); + ArrayPrototypePushApply(this[kBuffer], entries); + kPending.add(this); + if (kPending.size) + queuePending(); + } } if (this[kEntryTypes].size) @@ -249,7 +288,7 @@ class PerformanceObserver { takeRecords() { const list = this[kBuffer]; this[kBuffer] = []; - return new PerformanceObserverEntryList(list); + return list; } static get supportedEntryTypes() { @@ -265,7 +304,10 @@ class PerformanceObserver { queuePending(); } - [kDispatch]() { this[kCallback](this.takeRecords(), this); } + [kDispatch]() { + this[kCallback](new PerformanceObserverEntryList(this.takeRecords()), + this); + } [kInspect](depth, options) { if (depth < 0) return this; @@ -291,6 +333,102 @@ function enqueue(entry) { for (const obs of kObservers) { obs[kMaybeBuffer](entry); } + + const entryType = entry.entryType; + let buffer; + if (entryType === 'mark') { + buffer = markEntryBuffer; + } else if (entryType === 'measure') { + buffer = measureEntryBuffer; + } else { + return; + } + + const count = buffer.count + 1; + buffer.count = count; + if (count === 1) { + buffer.head = entry; + buffer.tail = entry; + return; + } + buffer.tail[kBufferNext] = entry; + buffer.tail = entry; + + if (count > kMaxPerformanceEntryBuffers && + !kWarnedEntryTypes.has(entryType)) { + kWarnedEntryTypes.set(entryType, true); + // No error code for this since it is a Warning + // eslint-disable-next-line no-restricted-syntax + const w = new Error('Possible perf_hooks memory leak detected. ' + + `${count} ${entryType} entries added to the global ` + + 'performance entry buffer. Use ' + + `${kClearPerformanceEntryBuffers[entryType]} to ` + + 'clear the buffer.'); + w.name = 'MaxPerformanceEntryBufferExceededWarning'; + w.entryType = entryType; + w.count = count; + process.emitWarning(w); + } +} + +function clearEntriesFromBuffer(type, name) { + let buffer; + if (type === 'mark') { + buffer = markEntryBuffer; + } else if (type === 'measure') { + buffer = measureEntryBuffer; + } else { + return; + } + if (name === undefined) { + resetBuffer(buffer); + return; + } + + let head = null; + let tail = null; + let count = 0; + for (let entry = buffer.head; entry !== null; entry = entry[kBufferNext]) { + if (entry.name !== name) { + head = head ?? entry; + tail = entry; + continue; + } + if (tail === null) { + continue; + } + tail[kBufferNext] = entry[kBufferNext]; + count++; + } + buffer.head = head; + buffer.tail = tail; + buffer.count = count; +} + +function filterBufferMapByNameAndType(name, type) { + let bufferList; + if (type === 'mark') { + bufferList = [markEntryBuffer]; + } else if (type === 'measure') { + bufferList = [measureEntryBuffer]; + } else if (type !== undefined) { + // Unrecognized type; + return []; + } else { + bufferList = [markEntryBuffer, measureEntryBuffer]; + } + return ArrayPrototypeFlatMap(bufferList, + (buffer) => filterBufferByName(buffer, name)); +} + +function filterBufferByName(buffer, name) { + const arr = []; + for (let entry = buffer.head; entry !== null; entry = entry[kBufferNext]) { + if (name === undefined || entry.name === name) { + ArrayPrototypePush(arr, entry); + } + } + return arr; } function observerCallback(name, type, startTime, duration, details) { @@ -338,8 +476,25 @@ function hasObserver(type) { return observerCounts[observerType] > 0; } +function createBuffer() { + return { + head: null, + tail: null, + count: 0, + }; +} + +function resetBuffer(buffer) { + buffer.head = null; + buffer.tail = null; + buffer.count = 0; +} + module.exports = { PerformanceObserver, + PerformanceObserverEntryList, enqueue, hasObserver, + clearEntriesFromBuffer, + filterBufferMapByNameAndType, }; diff --git a/lib/internal/perf/performance.js b/lib/internal/perf/performance.js index ca4aed90e4e270..38dac0ee32397c 100644 --- a/lib/internal/perf/performance.js +++ b/lib/internal/perf/performance.js @@ -4,9 +4,14 @@ const { ObjectDefineProperty, ObjectDefineProperties, ObjectSetPrototypeOf, - TypeError, } = primordials; +const { + codes: { + ERR_ILLEGAL_CONSTRUCTOR, + } +} = require('internal/errors'); + const { EventTarget, } = require('internal/event_target'); @@ -16,8 +21,12 @@ const { now } = require('internal/perf/utils'); const { mark, measure, - clearMarks, + clearMarkTimings, } = require('internal/perf/usertiming'); +const { + clearEntriesFromBuffer, + filterBufferMapByNameAndType, +} = require('internal/perf/observe'); const eventLoopUtilization = require('internal/perf/event_loop_utilization'); const nodeTiming = require('internal/perf/nodetiming'); @@ -31,8 +40,7 @@ const { class Performance extends EventTarget { constructor() { - // eslint-disable-next-line no-restricted-syntax - throw new TypeError('Illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } [kInspect](depth, options) { @@ -48,7 +56,6 @@ class Performance extends EventTarget { timeOrigin: this.timeOrigin, }, opts)}`; } - } function toJSON() { @@ -59,6 +66,39 @@ function toJSON() { }; } +function clearMarks(name) { + if (name !== undefined) { + name = `${name}`; + } + clearMarkTimings(name); + clearEntriesFromBuffer('mark', name); +} + +function clearMeasures(name) { + if (name !== undefined) { + name = `${name}`; + } + clearEntriesFromBuffer('measure', name); +} + +function getEntries() { + return filterBufferMapByNameAndType(); +} + +function getEntriesByName(name) { + if (name !== undefined) { + name = `${name}`; + } + return filterBufferMapByNameAndType(name, undefined); +} + +function getEntriesByType(type) { + if (type !== undefined) { + type = `${type}`; + } + return filterBufferMapByNameAndType(undefined, type); +} + class InternalPerformance extends EventTarget {} InternalPerformance.prototype.constructor = Performance.prototype.constructor; ObjectSetPrototypeOf(InternalPerformance.prototype, Performance.prototype); @@ -69,11 +109,31 @@ ObjectDefineProperties(Performance.prototype, { enumerable: false, value: clearMarks, }, + clearMeasures: { + configurable: true, + enumerable: false, + value: clearMeasures, + }, eventLoopUtilization: { configurable: true, enumerable: false, value: eventLoopUtilization, }, + getEntries: { + configurable: true, + enumerable: false, + value: getEntries, + }, + getEntriesByName: { + configurable: true, + enumerable: false, + value: getEntriesByName, + }, + getEntriesByType: { + configurable: true, + enumerable: false, + value: getEntriesByType, + }, mark: { configurable: true, enumerable: false, diff --git a/lib/internal/perf/performance_entry.js b/lib/internal/perf/performance_entry.js index f9f1c9e8966e2d..d8eedb9fb8f85b 100644 --- a/lib/internal/perf/performance_entry.js +++ b/lib/internal/perf/performance_entry.js @@ -3,9 +3,14 @@ const { ObjectSetPrototypeOf, Symbol, - TypeError, } = primordials; +const { + codes: { + ERR_ILLEGAL_CONSTRUCTOR, + } +} = require('internal/errors'); + const { customInspectSymbol: kInspect, } = require('internal/util'); @@ -17,6 +22,7 @@ const kType = Symbol('kType'); const kStart = Symbol('kStart'); const kDuration = Symbol('kDuration'); const kDetail = Symbol('kDetail'); +const kBufferNext = Symbol('kBufferNext'); function isPerformanceEntry(obj) { return obj?.[kName] !== undefined; @@ -24,8 +30,7 @@ function isPerformanceEntry(obj) { class PerformanceEntry { constructor() { - // eslint-disable-next-line no-restricted-syntax - throw new TypeError('illegal constructor'); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } get name() { return this[kName]; } @@ -67,6 +72,7 @@ class InternalPerformanceEntry { this[kStart] = start; this[kDuration] = duration; this[kDetail] = detail; + this[kBufferNext] = null; } } @@ -79,4 +85,5 @@ module.exports = { InternalPerformanceEntry, PerformanceEntry, isPerformanceEntry, + kBufferNext, }; diff --git a/lib/internal/perf/usertiming.js b/lib/internal/perf/usertiming.js index f83091de1919a8..496c75deb3b78f 100644 --- a/lib/internal/perf/usertiming.js +++ b/lib/internal/perf/usertiming.js @@ -1,10 +1,10 @@ 'use strict'; const { - ObjectKeys, SafeMap, SafeSet, SafeArrayIterator, + SymbolToStringTag, } = primordials; const { InternalPerformanceEntry } = require('internal/perf/performance_entry'); @@ -21,13 +21,14 @@ const { const { codes: { ERR_INVALID_ARG_VALUE, - ERR_INVALID_PERFORMANCE_MARK, ERR_PERFORMANCE_INVALID_TIMESTAMP, ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS, }, } = require('internal/errors'); -const marks = new SafeMap(); +const { structuredClone, lazyDOMException } = require('internal/util'); + +const markTimings = new SafeMap(); const nodeTimingReadOnlyAttributes = new SafeSet(new SafeArrayIterator([ 'nodeStart', @@ -48,60 +49,69 @@ function getMark(name) { name = `${name}`; if (nodeTimingReadOnlyAttributes.has(name)) return nodeTiming[name]; - const ts = marks.get(name); + const ts = markTimings.get(name); if (ts === undefined) - throw new ERR_INVALID_PERFORMANCE_MARK(name); + throw lazyDOMException(`The "${name}" performance mark has not been set`, 'SyntaxError'); return ts; } class PerformanceMark extends InternalPerformanceEntry { - constructor(name, options = {}) { + constructor(name, options) { name = `${name}`; if (nodeTimingReadOnlyAttributes.has(name)) throw new ERR_INVALID_ARG_VALUE('name', name); + options ??= {}; validateObject(options, 'options'); - const { - detail, - startTime = now(), - } = options; + const startTime = options.startTime ?? now(); validateNumber(startTime, 'startTime'); if (startTime < 0) throw new ERR_PERFORMANCE_INVALID_TIMESTAMP(startTime); - marks.set(name, startTime); + markTimings.set(name, startTime); + + let detail = options.detail; + detail = detail != null ? + structuredClone(detail) : + null; super(name, 'mark', startTime, 0, detail); - enqueue(this); + } + + get [SymbolToStringTag]() { + return 'PerformanceMark'; } } class PerformanceMeasure extends InternalPerformanceEntry { constructor(name, start, duration, detail) { super(name, 'measure', start, duration, detail); - enqueue(this); + } + + get [SymbolToStringTag]() { + return 'PerformanceMeasure'; } } function mark(name, options = {}) { - return new PerformanceMark(name, options); + const mark = new PerformanceMark(name, options); + enqueue(mark); + return mark; } function calculateStartDuration(startOrMeasureOptions, endMark) { startOrMeasureOptions ??= 0; - let detail; let start; let end; let duration; - if (typeof startOrMeasureOptions === 'object' && - ObjectKeys(startOrMeasureOptions).length) { - ({ - start, - end, - duration, - detail, - } = startOrMeasureOptions); + let optionsValid = false; + if (typeof startOrMeasureOptions === 'object') { + ({ start, end, duration } = startOrMeasureOptions); + optionsValid = start !== undefined || end !== undefined; + } + if (optionsValid) { if (endMark !== undefined) { throw new ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS( 'endMark must not be specified'); } + if (start === undefined && end === undefined) { throw new ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS( 'One of options.start or options.end is required'); @@ -111,21 +121,30 @@ function calculateStartDuration(startOrMeasureOptions, endMark) { 'Must not have options.start, options.end, and ' + 'options.duration specified'); } - start = getMark(start); - duration = getMark(duration); - } else { - start = getMark(startOrMeasureOptions); } - end = getMark(endMark || end) ?? - ((start !== undefined && duration !== undefined) ? - start + duration : now()); - - start ??= (duration !== undefined) ? end - duration : 0; + if (endMark !== undefined) { + end = getMark(endMark); + } else if (optionsValid && end !== undefined) { + end = getMark(end); + } else if (optionsValid && start !== undefined && duration !== undefined) { + end = getMark(start) + getMark(duration); + } else { + end = now(); + } - duration ??= end - start; + if (typeof startOrMeasureOptions === 'string') { + start = getMark(startOrMeasureOptions); + } else if (optionsValid && start !== undefined) { + start = getMark(start); + } else if (optionsValid && duration !== undefined && end !== undefined) { + start = end - getMark(duration); + } else { + start = 0; + } - return { start, duration, detail }; + duration = end - start; + return { start, duration }; } function measure(name, startOrMeasureOptions, endMark) { @@ -133,25 +152,29 @@ function measure(name, startOrMeasureOptions, endMark) { const { start, duration, - detail } = calculateStartDuration(startOrMeasureOptions, endMark); - return new PerformanceMeasure(name, start, duration, detail); + let detail = startOrMeasureOptions?.detail; + detail = detail != null ? structuredClone(detail) : null; + const measure = new PerformanceMeasure(name, start, duration, detail); + enqueue(measure); + return measure; } -function clearMarks(name) { +function clearMarkTimings(name) { if (name !== undefined) { name = `${name}`; if (nodeTimingReadOnlyAttributes.has(name)) throw new ERR_INVALID_ARG_VALUE('name', name); - marks.delete(name); + markTimings.delete(name); return; } - marks.clear(); + markTimings.clear(); } module.exports = { PerformanceMark, - clearMarks, + PerformanceMeasure, + clearMarkTimings, mark, measure, }; diff --git a/lib/internal/policy/manifest.js b/lib/internal/policy/manifest.js index c3ec82f596a509..a8420343db1a3c 100644 --- a/lib/internal/policy/manifest.js +++ b/lib/internal/policy/manifest.js @@ -501,8 +501,10 @@ class Manifest { value: expected } = integrityEntries[i]; const hash = createHash(algorithm); - HashUpdate(hash, content); - const digest = HashDigest(hash); + // TODO(tniessen): the content should not be passed as a string in the + // first place, see https://github.com/nodejs/node/issues/39707 + HashUpdate(hash, content, 'utf8'); + const digest = HashDigest(hash, 'buffer'); if (digest.length === expected.length && timingSafeEqual(digest, expected)) { return true; diff --git a/lib/internal/stream_base_commons.js b/lib/internal/stream_base_commons.js index 5254fc1553dd77..13b5f541cb88ef 100644 --- a/lib/internal/stream_base_commons.js +++ b/lib/internal/stream_base_commons.js @@ -80,7 +80,11 @@ function handleWriteReq(req, data, encoding) { function onWriteComplete(status) { debug('onWriteComplete', status, this.error); - const stream = this.handle[owner_symbol]; + let stream = this.handle[owner_symbol]; + + if (stream.constructor.name === 'ReusedHandle') { + stream = stream.handle; + } if (stream.destroyed) { if (typeof this.callback === 'function') @@ -168,7 +172,12 @@ function onStreamRead(arrayBuffer) { const nread = streamBaseState[kReadBytesOrError]; const handle = this; - const stream = this[owner_symbol]; + + let stream = this[owner_symbol]; + + if (stream.constructor.name === 'ReusedHandle') { + stream = stream.handle; + } stream[kUpdateTimer](); diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index d2d4f19ed3fa5c..d17dbda04e005b 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -167,6 +167,8 @@ function ReadableState(options, stream, isDuplex) { // If true, a maybeReadMore has been scheduled. this.readingMore = false; + this.dataEmitted = false; + this.decoder = null; this.encoding = null; if (options && options.encoding) { @@ -309,6 +311,7 @@ function addChunk(stream, state, chunk, addToFront) { } else { state.awaitDrainWriters = null; } + state.dataEmitted = true; stream.emit('data', chunk); } else { // Update the buffer info. @@ -519,8 +522,10 @@ Readable.prototype.read = function(n) { endReadable(this); } - if (ret !== null) + if (ret !== null) { + state.dataEmitted = true; this.emit('data', ret); + } return ret; }; @@ -1183,6 +1188,18 @@ ObjectDefineProperties(Readable.prototype, { } }, + readableDidRead: { + enumerable: false, + get: function() { + return ( + this._readableState.dataEmitted || + this._readableState.endEmitted || + this._readableState.errorEmitted || + this._readableState.closeEmitted + ); + } + }, + readableHighWaterMark: { enumerable: false, get: function() { @@ -1331,7 +1348,7 @@ function endReadableNT(state, stream) { stream.emit('end'); if (stream.writable && stream.allowHalfOpen === false) { - process.nextTick(endWritableNT, state, stream); + process.nextTick(endWritableNT, stream); } else if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the writable side is ready for autoDestroy as well. @@ -1350,7 +1367,7 @@ function endReadableNT(state, stream) { } } -function endWritableNT(state, stream) { +function endWritableNT(stream) { const writable = stream.writable && !stream.writableEnded && !stream.destroyed; if (writable) { diff --git a/lib/internal/tty.js b/lib/internal/tty.js index 5a247c7928c346..f8bfe8cf21a32b 100644 --- a/lib/internal/tty.js +++ b/lib/internal/tty.js @@ -29,10 +29,7 @@ const { StringPrototypeToLowerCase, } = primordials; -const { - ERR_INVALID_ARG_TYPE, - ERR_OUT_OF_RANGE -} = require('internal/errors').codes; +const { validateInteger } = require('internal/validators'); let OSRelease; @@ -221,13 +218,9 @@ function hasColors(count, env) { env = count; count = 16; } else { - if (typeof count !== 'number') { - throw new ERR_INVALID_ARG_TYPE('count', 'number', count); - } - if (count < 2) { - throw new ERR_OUT_OF_RANGE('count', '>= 2', count); - } + validateInteger(count, 'count', 2); } + return count <= 2 ** getColorDepth(env); } diff --git a/lib/internal/url.js b/lib/internal/url.js index 7d2bed80028d30..378248b9486b52 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -42,17 +42,20 @@ const { const { getConstructorOf, removeColors } = require('internal/util'); const { - ERR_ARG_NOT_ITERABLE, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_INVALID_FILE_URL_HOST, - ERR_INVALID_FILE_URL_PATH, - ERR_INVALID_THIS, - ERR_INVALID_TUPLE, - ERR_INVALID_URL, - ERR_INVALID_URL_SCHEME, - ERR_MISSING_ARGS -} = require('internal/errors').codes; + codes: { + ERR_ARG_NOT_ITERABLE, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_INVALID_FILE_URL_HOST, + ERR_INVALID_FILE_URL_PATH, + ERR_INVALID_THIS, + ERR_INVALID_TUPLE, + ERR_INVALID_URL, + ERR_INVALID_URL_SCHEME, + ERR_MISSING_ARGS, + ERR_NO_CRYPTO, + }, +} = require('internal/errors'); const { CHAR_AMPERSAND, CHAR_BACKWARD_SLASH, @@ -100,6 +103,11 @@ const { kSchemeStart } = internalBinding('url'); +const { + storeDataObject, + revokeDataObject, +} = internalBinding('blob'); + const context = Symbol('context'); const cannotBeBase = Symbol('cannot-be-base'); const cannotHaveUsernamePasswordPort = @@ -108,6 +116,24 @@ const special = Symbol('special'); const searchParams = Symbol('query'); const kFormat = Symbol('format'); +let blob; +let cryptoRandom; + +function lazyBlob() { + blob ??= require('internal/blob'); + return blob; +} + +function lazyCryptoRandom() { + try { + cryptoRandom ??= require('internal/crypto/random'); + } catch { + // If Node.js built without crypto support, we'll fall + // through here and handle it later. + } + return cryptoRandom; +} + // https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object const IteratorPrototype = ObjectGetPrototypeOf( ObjectGetPrototypeOf([][SymbolIterator]()) @@ -153,6 +179,10 @@ class URLContext { } } +function isURLSearchParams(self) { + return self && self[searchParams] && !self[searchParams][searchParams]; +} + class URLSearchParams { // URL Standard says the default value is '', but as undefined and '' have // the same result, undefined is used to prevent unnecessary parsing. @@ -222,9 +252,8 @@ class URLSearchParams { } [inspect.custom](recurseTimes, ctx) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } if (typeof recurseTimes === 'number' && recurseTimes < 0) return ctx.stylize('[Object]', 'special'); @@ -259,9 +288,9 @@ class URLSearchParams { } append(name, value) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 2) { throw new ERR_MISSING_ARGS('name', 'value'); } @@ -273,9 +302,9 @@ class URLSearchParams { } delete(name) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 1) { throw new ERR_MISSING_ARGS('name'); } @@ -294,9 +323,9 @@ class URLSearchParams { } get(name) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 1) { throw new ERR_MISSING_ARGS('name'); } @@ -312,9 +341,9 @@ class URLSearchParams { } getAll(name) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 1) { throw new ERR_MISSING_ARGS('name'); } @@ -331,9 +360,9 @@ class URLSearchParams { } has(name) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 1) { throw new ERR_MISSING_ARGS('name'); } @@ -349,9 +378,9 @@ class URLSearchParams { } set(name, value) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + if (arguments.length < 2) { throw new ERR_MISSING_ARGS('name', 'value'); } @@ -436,17 +465,16 @@ class URLSearchParams { // Define entries here rather than [Symbol.iterator] as the function name // must be set to `entries`. entries() { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } return createSearchParamsIterator(this, 'key+value'); } forEach(callback, thisArg = undefined) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } + validateCallback(callback); let list = this[searchParams]; @@ -464,17 +492,15 @@ class URLSearchParams { // https://heycam.github.io/webidl/#es-iterable keys() { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } return createSearchParamsIterator(this, 'key'); } values() { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } return createSearchParamsIterator(this, 'value'); } @@ -482,9 +508,8 @@ class URLSearchParams { // https://heycam.github.io/webidl/#es-stringifier // https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior toString() { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { + if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - } return serializeParams(this[searchParams]); } @@ -930,6 +955,37 @@ class URL { toJSON() { return this[kFormat]({}); } + + static createObjectURL(obj) { + const cryptoRandom = lazyCryptoRandom(); + if (cryptoRandom === undefined) + throw new ERR_NO_CRYPTO(); + + // Yes, lazy loading is annoying but because of circular + // references between the url, internal/blob, and buffer + // modules, lazy loading here makes sure that things work. + const blob = lazyBlob(); + if (!blob.isBlob(obj)) + throw new ERR_INVALID_ARG_TYPE('obj', 'Blob', obj); + + const id = cryptoRandom.randomUUID(); + + storeDataObject(id, obj[blob.kHandle], obj.size, obj.type); + + return `blob:nodedata:${id}`; + } + + static revokeObjectURL(url) { + url = `${url}`; + try { + const parsed = new URL(url); + const split = StringPrototypeSplit(parsed.pathname, ':'); + if (split.length === 2) + revokeDataObject(split[1]); + } catch { + // If there's an error, it's ignored. + } + } } ObjectDefineProperties(URL.prototype, { @@ -1303,7 +1359,7 @@ function urlToHttpOptions(url) { options.port = Number(url.port); } if (url.username || url.password) { - options.auth = `${url.username}:${url.password}`; + options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`; } return options; } diff --git a/lib/internal/util.js b/lib/internal/util.js index 101fbec67775b0..acaffb9ff27cf4 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -30,7 +30,6 @@ const { const { hideStackFrames, codes: { - ERR_INVALID_ARG_TYPE, ERR_NO_CRYPTO, ERR_UNKNOWN_SIGNAL }, @@ -75,6 +74,8 @@ function isError(e) { // each one once. const codesWarned = new SafeSet(); +let validateString; + // Mark that a method should not be used. // Returns a modified function which warns once by default. // If --no-deprecation is set, then it is a no-op. @@ -83,8 +84,12 @@ function deprecate(fn, msg, code) { return fn; } - if (code !== undefined && typeof code !== 'string') - throw new ERR_INVALID_ARG_TYPE('code', 'string', code); + // Lazy-load to avoid a circular dependency. + if (validateString === undefined) + ({ validateString } = require('internal/validators')); + + if (code !== undefined) + validateString(code, 'code'); let warned = false; function deprecated(...args) { @@ -300,15 +305,20 @@ function getSystemErrorMap() { const kCustomPromisifiedSymbol = SymbolFor('nodejs.util.promisify.custom'); const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs'); +let validateFunction; + function promisify(original) { - if (typeof original !== 'function') - throw new ERR_INVALID_ARG_TYPE('original', 'Function', original); + // Lazy-load to avoid a circular dependency. + if (validateFunction === undefined) + ({ validateFunction } = require('internal/validators')); + + validateFunction(original, 'original'); if (original[kCustomPromisifiedSymbol]) { const fn = original[kCustomPromisifiedSymbol]; - if (typeof fn !== 'function') { - throw new ERR_INVALID_ARG_TYPE('util.promisify.custom', 'Function', fn); - } + + validateFunction(fn, 'util.promisify.custom'); + return ObjectDefineProperty(fn, kCustomPromisifiedSymbol, { value: fn, enumerable: false, writable: false, configurable: true }); @@ -449,6 +459,21 @@ const lazyDOMException = hideStackFrames((message, name) => { return new DOMException(message, name); }); +function structuredClone(value) { + const { + DefaultSerializer, + DefaultDeserializer, + } = require('v8'); + const ser = new DefaultSerializer(); + ser._getDataCloneError = hideStackFrames((message) => + lazyDOMException(message, 'DataCloneError')); + ser.writeValue(value); + const serialized = ser.releaseBuffer(); + + const des = new DefaultDeserializer(serialized); + return des.readValue(); +} + module.exports = { assertCrypto, cachedResult, @@ -471,6 +496,7 @@ module.exports = { promisify, sleep, spliceOne, + structuredClone, removeColors, // Symbol used to customize promisify conversion diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 9bca0aa747725e..b3a7ee26554e1a 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -155,7 +155,7 @@ const validateObject = hideStackFrames( } }); -const validateArray = hideStackFrames((value, name, { minLength = 0 } = {}) => { +const validateArray = hideStackFrames((value, name, minLength = 0) => { if (!ArrayIsArray(value)) { throw new ERR_INVALID_ARG_TYPE(name, 'Array', value); } @@ -166,8 +166,7 @@ const validateArray = hideStackFrames((value, name, { minLength = 0 } = {}) => { }); function validateSignalName(signal, name = 'signal') { - if (typeof signal !== 'string') - throw new ERR_INVALID_ARG_TYPE(name, 'string', signal); + validateString(signal, name); if (signals[signal] === undefined) { if (signals[StringPrototypeToUpperCase(signal)] !== undefined) { @@ -199,7 +198,7 @@ function validateEncoding(data, encoding) { // Check that the port number is not NaN when coerced to a number, // is an integer and that it falls within the legal range of port numbers. -function validatePort(port, name = 'Port', { allowZero = true } = {}) { +function validatePort(port, name = 'Port', allowZero = true) { if ((typeof port !== 'number' && typeof port !== 'string') || (typeof port === 'string' && StringPrototypeTrim(port).length === 0) || +port !== (+port >>> 0) || diff --git a/lib/internal/worker/io.js b/lib/internal/worker/io.js index adacdd913c6693..95c5515d1414eb 100644 --- a/lib/internal/worker/io.js +++ b/lib/internal/worker/io.js @@ -53,6 +53,7 @@ const { inspect } = require('internal/util/inspect'); const { codes: { ERR_INVALID_ARG_TYPE, + ERR_INVALID_THIS, ERR_MISSING_ARGS, } } = require('internal/errors'); @@ -74,6 +75,7 @@ const kStartedReading = Symbol('kStartedReading'); const kStdioWantsMoreDataCallback = Symbol('kStdioWantsMoreDataCallback'); const kCurrentlyReceivingPorts = SymbolFor('nodejs.internal.kCurrentlyReceivingPorts'); +const kType = Symbol('kType'); const messageTypes = { UP_AND_RUNNING: 'upAndRunning', @@ -349,11 +351,16 @@ function onMessageEvent(type, data) { this.dispatchEvent(new MessageEvent(type, { data })); } +function isBroadcastChannel(value) { + return value?.[kType] === 'BroadcastChannel'; +} + class BroadcastChannel extends EventTarget { constructor(name) { if (arguments.length === 0) throw new ERR_MISSING_ARGS('name'); super(); + this[kType] = 'BroadcastChannel'; this[kName] = `${name}`; this[kHandle] = broadcastChannel(this[kName]); this[kOnMessage] = FunctionPrototypeBind(onMessageEvent, this, 'message'); @@ -364,6 +371,8 @@ class BroadcastChannel extends EventTarget { } [inspect.custom](depth, options) { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); if (depth < 0) return 'BroadcastChannel'; @@ -378,9 +387,15 @@ class BroadcastChannel extends EventTarget { }, opts)}`; } - get name() { return this[kName]; } + get name() { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); + return this[kName]; + } close() { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); if (this[kHandle] === undefined) return; this[kHandle].off('message', this[kOnMessage]); @@ -392,6 +407,8 @@ class BroadcastChannel extends EventTarget { } postMessage(message) { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); if (arguments.length === 0) throw new ERR_MISSING_ARGS('message'); if (this[kHandle] === undefined) @@ -400,19 +417,40 @@ class BroadcastChannel extends EventTarget { throw new DOMException('Message could not be posted.'); } + // The ref() method is Node.js specific and not part of the standard + // BroadcastChannel API definition. Typically we shouldn't extend Web + // Platform APIs with Node.js specific methods but ref and unref + // are a bit special. ref() { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); if (this[kHandle]) this[kHandle].ref(); return this; } + // The unref() method is Node.js specific and not part of the standard + // BroadcastChannel API definition. Typically we shouldn't extend Web + // Platform APIs with Node.js specific methods but ref and unref + // are a bit special. unref() { + if (!isBroadcastChannel(this)) + throw new ERR_INVALID_THIS('BroadcastChannel'); if (this[kHandle]) this[kHandle].unref(); return this; } } +const kEnumerableProperty = ObjectCreate(null); +kEnumerableProperty.enumerable = true; + +ObjectDefineProperties(BroadcastChannel.prototype, { + name: kEnumerableProperty, + close: kEnumerableProperty, + postMessage: kEnumerableProperty, +}); + defineEventHandler(BroadcastChannel.prototype, 'message'); defineEventHandler(BroadcastChannel.prototype, 'messageerror'); diff --git a/lib/net.js b/lib/net.js index 20601007fab695..ded48732c2e11e 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1102,7 +1102,11 @@ Socket.prototype.unref = function() { function afterConnect(status, handle, req, readable, writable) { - const self = handle[owner_symbol]; + let self = handle[owner_symbol]; + + if (self.constructor.name === 'ReusedHandle') { + self = self.handle; + } // Callback may come after call to destroy if (self.destroyed) { diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js index 339d3ca4ff0ab4..74ba890f537bc2 100644 --- a/lib/perf_hooks.js +++ b/lib/perf_hooks.js @@ -9,8 +9,14 @@ const { } = internalBinding('performance'); const { PerformanceEntry } = require('internal/perf/performance_entry'); -const { PerformanceObserver } = require('internal/perf/observe'); -const { PerformanceMark } = require('internal/perf/usertiming'); +const { + PerformanceObserver, + PerformanceObserverEntryList, +} = require('internal/perf/observe'); +const { + PerformanceMark, + PerformanceMeasure, +} = require('internal/perf/usertiming'); const { InternalPerformance } = require('internal/perf/performance'); const { @@ -22,7 +28,9 @@ const monitorEventLoopDelay = require('internal/perf/event_loop_delay'); module.exports = { PerformanceEntry, PerformanceMark, + PerformanceMeasure, PerformanceObserver, + PerformanceObserverEntryList, monitorEventLoopDelay, createHistogram, performance: new InternalPerformance(), diff --git a/lib/stream/consumers.js b/lib/stream/consumers.js new file mode 100644 index 00000000000000..4566eff6a30f7f --- /dev/null +++ b/lib/stream/consumers.js @@ -0,0 +1,87 @@ +'use strict'; + +const { + JSONParse, +} = primordials; + +const { + TextDecoder, +} = require('internal/encoding'); + +const { + Blob, +} = require('internal/blob'); + +const { + Buffer, +} = require('buffer'); + +/** + * @typedef {import('../internal/webstreams/readablestream').ReadableStream + * } ReadableStream + * @typedef {import('../internal/streams/readable')} Readable + */ + +/** + * @param {AsyncIterable|ReadableStream|Readable} stream + * @returns {Promise} + */ +async function blob(stream) { + const chunks = []; + for await (const chunk of stream) + chunks.push(chunk); + return new Blob(chunks); +} + +/** + * @param {AsyncIterable|ReadableStream|Readable} stream + * @returns {Promise} + */ +async function arrayBuffer(stream) { + const ret = await blob(stream); + return ret.arrayBuffer(); +} + +/** + * @param {AsyncIterable|ReadableStream|Readable} stream + * @returns {Promise} + */ +async function buffer(stream) { + return Buffer.from(await arrayBuffer(stream)); +} + +/** + * @param {AsyncIterable|ReadableStream|Readable} stream + * @returns {Promise} + */ +async function text(stream) { + const dec = new TextDecoder(); + let str = ''; + for await (const chunk of stream) { + if (typeof chunk === 'string') + str += chunk; + else + str += dec.decode(chunk, { stream: true }); + } + // Flush the streaming TextDecoder so that any pending + // incomplete multibyte characters are handled. + str += dec.decode(undefined, { stream: false }); + return str; +} + +/** + * @param {AsyncIterable|ReadableStream|Readable} stream + * @returns {Promise} + */ +async function json(stream) { + const str = await text(stream); + return JSONParse(str); +} + +module.exports = { + arrayBuffer, + blob, + buffer, + text, + json, +}; diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 3fb2f8c309825c..59b842b232517b 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -313,7 +313,7 @@ void AsyncWrap::EmitDestroy(bool from_gc) { if (!persistent().IsEmpty() && !from_gc) { HandleScope handle_scope(env()->isolate()); - USE(object()->Set(env()->context(), env()->resource_symbol(), object())); + USE(object()->Set(env()->context(), env()->owner_symbol(), object())); } } @@ -586,7 +586,7 @@ void AsyncWrap::AsyncReset(Local resource, double execution_async_id, Local obj = object(); CHECK(!obj.IsEmpty()); if (resource != obj) { - USE(obj->Set(env()->context(), env()->resource_symbol(), resource)); + USE(obj->Set(env()->context(), env()->owner_symbol(), resource)); } } diff --git a/src/async_wrap.h b/src/async_wrap.h index 522779d57a0448..10d02c15da8f27 100644 --- a/src/async_wrap.h +++ b/src/async_wrap.h @@ -38,7 +38,7 @@ namespace node { V(ELDHISTOGRAM) \ V(FILEHANDLE) \ V(FILEHANDLECLOSEREQ) \ - V(FIXEDSIZEBLOBCOPY) \ + V(FIXEDSIZEBLOBCOPY) \ V(FSEVENTWRAP) \ V(FSREQCALLBACK) \ V(FSREQPROMISE) \ diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index f4b069a28ea2c6..edc86761876224 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -63,7 +63,10 @@ using v8::HandleScope; using v8::Int32; using v8::Integer; using v8::Isolate; +using v8::Just; using v8::Local; +using v8::Maybe; +using v8::Nothing; using v8::Null; using v8::Object; using v8::String; @@ -631,9 +634,14 @@ int ParseSoaReply( } } // anonymous namespace -ChannelWrap::ChannelWrap(Environment* env, Local object, int timeout) +ChannelWrap::ChannelWrap( + Environment* env, + Local object, + int timeout, + int tries) : AsyncWrap(env, object, PROVIDER_DNSCHANNEL), - timeout_(timeout) { + timeout_(timeout), + tries_(tries) { MakeWeak(); Setup(); @@ -647,11 +655,13 @@ void ChannelWrap::MemoryInfo(MemoryTracker* tracker) const { void ChannelWrap::New(const FunctionCallbackInfo& args) { CHECK(args.IsConstructCall()); - CHECK_EQ(args.Length(), 1); + CHECK_EQ(args.Length(), 2); CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsInt32()); const int timeout = args[0].As()->Value(); + const int tries = args[1].As()->Value(); Environment* env = Environment::GetCurrent(args); - new ChannelWrap(env, args.This(), timeout); + new ChannelWrap(env, args.This(), timeout, tries); } GetAddrInfoReqWrap::GetAddrInfoReqWrap( @@ -704,6 +714,7 @@ void ChannelWrap::Setup() { options.sock_state_cb = ares_sockstate_cb; options.sock_state_cb_data = this; options.timeout = timeout_; + options.tries = tries_; int r; if (!library_inited_) { @@ -717,7 +728,8 @@ void ChannelWrap::Setup() { /* We do the call to ares_init_option for caller. */ const int optmask = - ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | ARES_OPT_SOCK_STATE_CB; + ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | + ARES_OPT_SOCK_STATE_CB | ARES_OPT_TRIES; r = ares_init_options(&channel_, &options, optmask); if (r != ARES_SUCCESS) { @@ -1434,7 +1446,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { if (status == 0) { Local results = Array::New(env->isolate()); - auto add = [&] (bool want_ipv4, bool want_ipv6) { + auto add = [&] (bool want_ipv4, bool want_ipv6) -> Maybe { for (auto p = res; p != nullptr; p = p->ai_next) { CHECK_EQ(p->ai_socktype, SOCK_STREAM); @@ -1454,14 +1466,19 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { continue; Local s = OneByteString(env->isolate(), ip); - results->Set(env->context(), n, s).Check(); + if (results->Set(env->context(), n, s).IsNothing()) + return Nothing(); n++; } + return Just(true); }; - add(true, verbatim); - if (verbatim == false) - add(false, true); + if (add(true, verbatim).IsNothing()) + return; + if (verbatim == false) { + if (add(false, true).IsNothing()) + return; + } // No responses were found to return if (n == 0) { diff --git a/src/cares_wrap.h b/src/cares_wrap.h index 8647868efde231..60f99e65edf348 100644 --- a/src/cares_wrap.h +++ b/src/cares_wrap.h @@ -147,7 +147,11 @@ struct NodeAresTask final : public MemoryRetainer { class ChannelWrap final : public AsyncWrap { public: - ChannelWrap(Environment* env, v8::Local object, int timeout); + ChannelWrap( + Environment* env, + v8::Local object, + int timeout, + int tries); ~ChannelWrap() override; static void New(const v8::FunctionCallbackInfo& args); @@ -181,6 +185,7 @@ class ChannelWrap final : public AsyncWrap { bool is_servers_default_ = true; bool library_inited_ = false; int timeout_; + int tries_; int active_query_count_ = 0; NodeAresTask::List task_list_; }; diff --git a/src/env.h b/src/env.h index e1b89261fcb1e9..24b4a48b5f9657 100644 --- a/src/env.h +++ b/src/env.h @@ -170,7 +170,6 @@ constexpr size_t kFsStatsBufferLength = V(oninit_symbol, "oninit") \ V(owner_symbol, "owner_symbol") \ V(onpskexchange_symbol, "onpskexchange") \ - V(resource_symbol, "resource_symbol") \ V(trigger_async_id_symbol, "trigger_async_id_symbol") \ // Strings are per-isolate primitives but Environment proxies them diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index fe3d8fbc977c2e..5d18980fc76a7b 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -306,12 +306,16 @@ class CallbackWrapperBase : public CallbackWrapper { napi_env env = _bundle->env; napi_callback cb = _bundle->cb; - napi_value result; + napi_value result = nullptr; + bool exceptionOccurred = false; env->CallIntoModule([&](napi_env env) { result = cb(env, cbinfo_wrapper); + }, [&](napi_env env, v8::Local value) { + exceptionOccurred = true; + env->isolate->ThrowException(value); }); - if (result != nullptr) { + if (!exceptionOccurred && (result != nullptr)) { this->SetReturnValue(result); } } diff --git a/src/node_binding.cc b/src/node_binding.cc index b5e42af79510b6..3c9776e655d0e4 100644 --- a/src/node_binding.cc +++ b/src/node_binding.cc @@ -40,6 +40,7 @@ // __attribute__((constructor)) like mechanism in GCC. #define NODE_BUILTIN_STANDARD_MODULES(V) \ V(async_wrap) \ + V(blob) \ V(block_list) \ V(buffer) \ V(cares_wrap) \ diff --git a/src/node_blob.cc b/src/node_blob.cc index 0b18bbce138e35..c583d5e0a93791 100644 --- a/src/node_blob.cc +++ b/src/node_blob.cc @@ -26,12 +26,26 @@ using v8::Local; using v8::MaybeLocal; using v8::Number; using v8::Object; +using v8::String; using v8::Uint32; using v8::Undefined; using v8::Value; -void Blob::Initialize(Environment* env, v8::Local target) { +void Blob::Initialize( + Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + + BlobBindingData* const binding_data = + env->AddBindingData(context, target); + if (binding_data == nullptr) return; + env->SetMethod(target, "createBlob", New); + env->SetMethod(target, "storeDataObject", StoreDataObject); + env->SetMethod(target, "getDataObject", GetDataObject); + env->SetMethod(target, "revokeDataObject", RevokeDataObject); FixedSizeBlobCopyJob::Initialize(env, target); } @@ -220,6 +234,78 @@ std::unique_ptr Blob::CloneForMessaging() const { return std::make_unique(store_, length_); } +void Blob::StoreDataObject(const v8::FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + BlobBindingData* binding_data = + Environment::GetBindingData(args); + + CHECK(args[0]->IsString()); // ID key + CHECK(Blob::HasInstance(env, args[1])); // Blob + CHECK(args[2]->IsUint32()); // Length + CHECK(args[3]->IsString()); // Type + + Utf8Value key(env->isolate(), args[0]); + Blob* blob; + ASSIGN_OR_RETURN_UNWRAP(&blob, args[1]); + + size_t length = args[2].As()->Value(); + Utf8Value type(env->isolate(), args[3]); + + binding_data->store_data_object( + std::string(*key, key.length()), + BlobBindingData::StoredDataObject( + BaseObjectPtr(blob), + length, + std::string(*type, type.length()))); +} + +void Blob::RevokeDataObject(const v8::FunctionCallbackInfo& args) { + BlobBindingData* binding_data = + Environment::GetBindingData(args); + + Environment* env = Environment::GetCurrent(args); + CHECK(args[0]->IsString()); // ID key + + Utf8Value key(env->isolate(), args[0]); + + binding_data->revoke_data_object(std::string(*key, key.length())); +} + +void Blob::GetDataObject(const v8::FunctionCallbackInfo& args) { + BlobBindingData* binding_data = + Environment::GetBindingData(args); + + Environment* env = Environment::GetCurrent(args); + CHECK(args[0]->IsString()); + + Utf8Value key(env->isolate(), args[0]); + + BlobBindingData::StoredDataObject stored = + binding_data->get_data_object(std::string(*key, key.length())); + if (stored.blob) { + Local type; + if (!String::NewFromUtf8( + env->isolate(), + stored.type.c_str(), + v8::NewStringType::kNormal, + static_cast(stored.type.length())).ToLocal(&type)) { + return; + } + + Local values[] = { + stored.blob->object(), + Uint32::NewFromUnsigned(env->isolate(), stored.length), + type + }; + + args.GetReturnValue().Set( + Array::New( + env->isolate(), + values, + arraysize(values))); + } +} + FixedSizeBlobCopyJob::FixedSizeBlobCopyJob( Environment* env, Local object, @@ -328,10 +414,88 @@ void FixedSizeBlobCopyJob::RegisterExternalReferences( registry->Register(Run); } +void BlobBindingData::StoredDataObject::MemoryInfo( + MemoryTracker* tracker) const { + tracker->TrackField("blob", blob); + tracker->TrackFieldWithSize("type", type.length()); +} + +BlobBindingData::StoredDataObject::StoredDataObject( + const BaseObjectPtr& blob_, + size_t length_, + const std::string& type_) + : blob(blob_), + length(length_), + type(type_) {} + +BlobBindingData::BlobBindingData(Environment* env, Local wrap) + : SnapshotableObject(env, wrap, type_int) { + MakeWeak(); +} + +void BlobBindingData::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("data_objects", data_objects_); +} + +void BlobBindingData::store_data_object( + const std::string& uuid, + const BlobBindingData::StoredDataObject& object) { + data_objects_[uuid] = object; +} + +void BlobBindingData::revoke_data_object(const std::string& uuid) { + CHECK_NE(data_objects_.find(uuid), data_objects_.end()); + data_objects_.erase(uuid); + CHECK_EQ(data_objects_.find(uuid), data_objects_.end()); +} + +BlobBindingData::StoredDataObject BlobBindingData::get_data_object( + const std::string& uuid) { + auto entry = data_objects_.find(uuid); + if (entry == data_objects_.end()) + return BlobBindingData::StoredDataObject {}; + return entry->second; +} + +void BlobBindingData::Deserialize( + Local context, + Local holder, + int index, + InternalFieldInfo* info) { + DCHECK_EQ(index, BaseObject::kSlot); + HandleScope scope(context->GetIsolate()); + Environment* env = Environment::GetCurrent(context); + BlobBindingData* binding = + env->AddBindingData(context, holder); + CHECK_NOT_NULL(binding); +} + +void BlobBindingData::PrepareForSerialization( + Local context, + v8::SnapshotCreator* creator) { + // Stored blob objects are not actually persisted. +} + +InternalFieldInfo* BlobBindingData::Serialize(int index) { + DCHECK_EQ(index, BaseObject::kSlot); + InternalFieldInfo* info = InternalFieldInfo::New(type()); + return info; +} + +constexpr FastStringKey BlobBindingData::type_name; + void Blob::RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(Blob::New); registry->Register(Blob::ToArrayBuffer); registry->Register(Blob::ToSlice); + registry->Register(Blob::StoreDataObject); + registry->Register(Blob::GetDataObject); + registry->Register(Blob::RevokeDataObject); + + FixedSizeBlobCopyJob::RegisterExternalReferences(registry); } } // namespace node + +NODE_MODULE_CONTEXT_AWARE_INTERNAL(blob, node::Blob::Initialize); +NODE_MODULE_EXTERNAL_REFERENCE(blob, node::Blob::RegisterExternalReferences); diff --git a/src/node_blob.h b/src/node_blob.h index 9d6178996c8fd5..61f4da655c93cd 100644 --- a/src/node_blob.h +++ b/src/node_blob.h @@ -8,9 +8,12 @@ #include "env.h" #include "memory_tracker.h" #include "node_internals.h" +#include "node_snapshotable.h" #include "node_worker.h" #include "v8.h" +#include +#include #include namespace node { @@ -25,11 +28,19 @@ class Blob : public BaseObject { public: static void RegisterExternalReferences( ExternalReferenceRegistry* registry); - static void Initialize(Environment* env, v8::Local target); + + static void Initialize( + v8::Local target, + v8::Local unused, + v8::Local context, + void* priv); static void New(const v8::FunctionCallbackInfo& args); static void ToArrayBuffer(const v8::FunctionCallbackInfo& args); static void ToSlice(const v8::FunctionCallbackInfo& args); + static void StoreDataObject(const v8::FunctionCallbackInfo& args); + static void GetDataObject(const v8::FunctionCallbackInfo& args); + static void RevokeDataObject(const v8::FunctionCallbackInfo& args); static v8::Local GetConstructorTemplate( Environment* env); @@ -131,6 +142,49 @@ class FixedSizeBlobCopyJob : public AsyncWrap, public ThreadPoolWork { size_t length_ = 0; }; +class BlobBindingData : public SnapshotableObject { + public: + explicit BlobBindingData(Environment* env, v8::Local wrap); + + SERIALIZABLE_OBJECT_METHODS() + + static constexpr FastStringKey type_name{"node::BlobBindingData"}; + static constexpr EmbedderObjectType type_int = + EmbedderObjectType::k_blob_binding_data; + + void MemoryInfo(MemoryTracker* tracker) const override; + SET_SELF_SIZE(BlobBindingData) + SET_MEMORY_INFO_NAME(BlobBindingData) + + struct StoredDataObject : public MemoryRetainer { + BaseObjectPtr blob; + size_t length; + std::string type; + + StoredDataObject() = default; + + StoredDataObject( + const BaseObjectPtr& blob_, + size_t length_, + const std::string& type_); + + void MemoryInfo(MemoryTracker* tracker) const override; + SET_SELF_SIZE(StoredDataObject) + SET_MEMORY_INFO_NAME(StoredDataObject) + }; + + void store_data_object( + const std::string& uuid, + const StoredDataObject& object); + + void revoke_data_object(const std::string& uuid); + + StoredDataObject get_data_object(const std::string& uuid); + + private: + std::unordered_map data_objects_; +}; + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/node_buffer.cc b/src/node_buffer.cc index b5651b5e325fc9..962a4a11aab8e6 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -1266,8 +1266,6 @@ void Initialize(Local target, env->SetMethod(target, "utf8Write", StringWrite); env->SetMethod(target, "getZeroFillToggle", GetZeroFillToggle); - - Blob::Initialize(env, target); } } // anonymous namespace @@ -1311,9 +1309,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(DetachArrayBuffer); registry->Register(CopyArrayBuffer); - - Blob::RegisterExternalReferences(registry); - FixedSizeBlobCopyJob::RegisterExternalReferences(registry); } } // namespace Buffer diff --git a/src/node_external_reference.h b/src/node_external_reference.h index 094558783f770e..8d2de64ad43445 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -49,6 +49,7 @@ class ExternalReferenceRegistry { #define EXTERNAL_REFERENCE_BINDING_LIST_BASE(V) \ V(async_wrap) \ V(binding) \ + V(blob) \ V(buffer) \ V(contextify) \ V(credentials) \ diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 8a08a95bf75d42..b1b3f5d1749a4f 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -442,11 +442,24 @@ void ConverterObject::Decode(const FunctionCallbackInfo& args) { UErrorCode status = U_ZERO_ERROR; MaybeStackBuffer result; MaybeLocal ret; - size_t limit = converter->min_char_size() * input.length(); + + UBool flush = (flags & CONVERTER_FLAGS_FLUSH) == CONVERTER_FLAGS_FLUSH; + + // When flushing the final chunk, the limit is the maximum + // of either the input buffer length or the number of pending + // characters times the min char size. + size_t limit = converter->min_char_size() * + (!flush ? + input.length() : + std::max( + input.length(), + static_cast( + ucnv_toUCountPending(converter->conv(), &status)))); + status = U_ZERO_ERROR; + if (limit > 0) result.AllocateSufficientStorage(limit); - UBool flush = (flags & CONVERTER_FLAGS_FLUSH) == CONVERTER_FLAGS_FLUSH; auto cleanup = OnScopeLeave([&]() { if (flush) { // Reset the converter state. diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 35e0ed3f6df4bf..6e284bb66a0de5 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -5,6 +5,7 @@ #include "base_object-inl.h" #include "debug_utils-inl.h" #include "env-inl.h" +#include "node_blob.h" #include "node_errors.h" #include "node_external_reference.h" #include "node_file.h" diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h index 38da68f6d28eb2..ceb84fc9bf0382 100644 --- a/src/node_snapshotable.h +++ b/src/node_snapshotable.h @@ -15,7 +15,8 @@ struct SnapshotData; #define SERIALIZABLE_OBJECT_TYPES(V) \ V(fs_binding_data, fs::BindingData) \ - V(v8_binding_data, v8_utils::BindingData) + V(v8_binding_data, v8_utils::BindingData) \ + V(blob_binding_data, BlobBindingData) enum class EmbedderObjectType : uint8_t { k_default = 0, diff --git a/src/node_version.h b/src/node_version.h index fe5c92233c5a4f..ee1263b8eaaab6 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 16 -#define NODE_MINOR_VERSION 6 -#define NODE_PATCH_VERSION 3 +#define NODE_MINOR_VERSION 7 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/test/async-hooks/test-http-agent-handle-reuse-parallel.js b/test/async-hooks/test-http-agent-handle-reuse-parallel.js index cd73b3ed2cb61c..a7d76a694b24d3 100644 --- a/test/async-hooks/test-http-agent-handle-reuse-parallel.js +++ b/test/async-hooks/test-http-agent-handle-reuse-parallel.js @@ -87,6 +87,4 @@ function onExit() { // Verify reuse handle has been wrapped assert.strictEqual(first.type, second.type); assert.ok(first.handle !== second.handle, 'Resource reused'); - assert.ok(first.handle === second.handle.handle, - 'Resource not wrapped correctly'); } diff --git a/test/async-hooks/test-http-agent-handle-reuse-serial.js b/test/async-hooks/test-http-agent-handle-reuse-serial.js index bbc7183d6e72ca..2ee118bb240a36 100644 --- a/test/async-hooks/test-http-agent-handle-reuse-serial.js +++ b/test/async-hooks/test-http-agent-handle-reuse-serial.js @@ -105,6 +105,4 @@ function onExit() { // Verify reuse handle has been wrapped assert.strictEqual(first.type, second.type); assert.ok(first.handle !== second.handle, 'Resource reused'); - assert.ok(first.handle === second.handle.handle, - 'Resource not wrapped correctly'); } diff --git a/test/common/index.js b/test/common/index.js index 0f0885997ce9a1..2ac4538cbea804 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -286,6 +286,12 @@ if (global.gc) { if (global.performance) { knownGlobals.push(global.performance); } +if (global.PerformanceMark) { + knownGlobals.push(global.PerformanceMark); +} +if (global.PerformanceMeasure) { + knownGlobals.push(global.PerformanceMeasure); +} function allowGlobals(...allowlist) { knownGlobals = knownGlobals.concat(allowlist); diff --git a/test/fixtures/copy/kitchen-sink/README.md b/test/fixtures/copy/kitchen-sink/README.md new file mode 100644 index 00000000000000..fec56017dc1b1a --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/README.md @@ -0,0 +1 @@ +# Hello diff --git a/test/fixtures/copy/kitchen-sink/a/b/README2.md b/test/fixtures/copy/kitchen-sink/a/b/README2.md new file mode 100644 index 00000000000000..fec56017dc1b1a --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/b/README2.md @@ -0,0 +1 @@ +# Hello diff --git a/test/fixtures/copy/kitchen-sink/a/b/index.js b/test/fixtures/copy/kitchen-sink/a/b/index.js new file mode 100644 index 00000000000000..12388b0457bdda --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/b/index.js @@ -0,0 +1,3 @@ +module.exports = { + purpose: 'testing copy' +}; diff --git a/test/fixtures/copy/kitchen-sink/a/c/README2.md b/test/fixtures/copy/kitchen-sink/a/c/README2.md new file mode 100644 index 00000000000000..fec56017dc1b1a --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/c/README2.md @@ -0,0 +1 @@ +# Hello diff --git a/test/fixtures/copy/kitchen-sink/a/c/d/README3.md b/test/fixtures/copy/kitchen-sink/a/c/d/README3.md new file mode 100644 index 00000000000000..fec56017dc1b1a --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/c/d/README3.md @@ -0,0 +1 @@ +# Hello diff --git a/test/fixtures/copy/kitchen-sink/a/c/d/index.js b/test/fixtures/copy/kitchen-sink/a/c/d/index.js new file mode 100644 index 00000000000000..12388b0457bdda --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/c/d/index.js @@ -0,0 +1,3 @@ +module.exports = { + purpose: 'testing copy' +}; diff --git a/test/fixtures/copy/kitchen-sink/a/c/index.js b/test/fixtures/copy/kitchen-sink/a/c/index.js new file mode 100644 index 00000000000000..12388b0457bdda --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/c/index.js @@ -0,0 +1,3 @@ +module.exports = { + purpose: 'testing copy' +}; diff --git a/test/fixtures/copy/kitchen-sink/a/index.js b/test/fixtures/copy/kitchen-sink/a/index.js new file mode 100644 index 00000000000000..12388b0457bdda --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/a/index.js @@ -0,0 +1,3 @@ +module.exports = { + purpose: 'testing copy' +}; diff --git a/test/fixtures/copy/kitchen-sink/index.js b/test/fixtures/copy/kitchen-sink/index.js new file mode 100644 index 00000000000000..12388b0457bdda --- /dev/null +++ b/test/fixtures/copy/kitchen-sink/index.js @@ -0,0 +1,3 @@ +module.exports = { + purpose: 'testing copy' +}; diff --git a/test/fixtures/policy/crypto-default-encoding/.gitattributes b/test/fixtures/policy/crypto-default-encoding/.gitattributes new file mode 100644 index 00000000000000..cbdcbbc258e6e7 --- /dev/null +++ b/test/fixtures/policy/crypto-default-encoding/.gitattributes @@ -0,0 +1 @@ +*.js text eol=lf diff --git a/test/fixtures/policy/crypto-default-encoding/dep.js b/test/fixtures/policy/crypto-default-encoding/dep.js new file mode 100644 index 00000000000000..d741da76db0076 --- /dev/null +++ b/test/fixtures/policy/crypto-default-encoding/dep.js @@ -0,0 +1,3 @@ +'use strict'; + +// No code. diff --git a/test/fixtures/policy/crypto-default-encoding/parent.js b/test/fixtures/policy/crypto-default-encoding/parent.js new file mode 100644 index 00000000000000..90ebde7e6535c0 --- /dev/null +++ b/test/fixtures/policy/crypto-default-encoding/parent.js @@ -0,0 +1,4 @@ +'use strict'; + +require('crypto').DEFAULT_ENCODING = process.env.DEFAULT_ENCODING; +require('./dep.js'); diff --git a/test/fixtures/policy/crypto-default-encoding/policy.json b/test/fixtures/policy/crypto-default-encoding/policy.json new file mode 100644 index 00000000000000..4cb485e1d9e2e4 --- /dev/null +++ b/test/fixtures/policy/crypto-default-encoding/policy.json @@ -0,0 +1,14 @@ +{ + "resources": { + "./parent.js": { + "integrity": "sha384-j4pMdq83q5Bq9+idcHuGKzi89FrYm1PhZYrEw3irbNob6g4i3vKBjfYiRNYwmoGr", + "dependencies": { + "crypto": true, + "./dep.js": true + } + }, + "./dep.js": { + "integrity": "sha384-VU7GIrTix/HFLhUb4yqsV4n1xXqjPcWw6kLvjuKXtR1+9nmufJu5vZLajBs8brIW" + } + } +} diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 6019abd8aa8769..7c795981d793a6 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -10,19 +10,22 @@ See [test/wpt](../../wpt/README.md) for information on how these tests are run. Last update: -- common: https://github.com/web-platform-tests/wpt/tree/bb97a68974/common +- common: https://github.com/web-platform-tests/wpt/tree/03c5072aff/common - console: https://github.com/web-platform-tests/wpt/tree/3b1f72e99a/console -- dom/abort: https://github.com/web-platform-tests/wpt/tree/1728d198c9/dom/abort +- dom/abort: https://github.com/web-platform-tests/wpt/tree/c49cafb491/dom/abort - encoding: https://github.com/web-platform-tests/wpt/tree/35f70910d3/encoding - FileAPI: https://github.com/web-platform-tests/wpt/tree/3b279420d4/FileAPI - hr-time: https://github.com/web-platform-tests/wpt/tree/9910784394/hr-time - html/webappapis/atob: https://github.com/web-platform-tests/wpt/tree/f267e1dca6/html/webappapis/atob - html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/2c5c3c4c27/html/webappapis/microtask-queuing - html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers -- interfaces: https://github.com/web-platform-tests/wpt/tree/fcb671ed8b/interfaces -- resources: https://github.com/web-platform-tests/wpt/tree/972ca5b669/resources +- interfaces: https://github.com/web-platform-tests/wpt/tree/fc086c82d5/interfaces +- performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline +- resources: https://github.com/web-platform-tests/wpt/tree/fbee645164/resources - streams: https://github.com/web-platform-tests/wpt/tree/8f60d94439/streams - url: https://github.com/web-platform-tests/wpt/tree/77d54aa9e0/url +- user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/cdd0f03df4/WebCryptoAPI [Web Platform Tests]: https://github.com/web-platform-tests/wpt [`git node wpt`]: https://github.com/nodejs/node-core-utils/blob/main/docs/git-node.md#git-node-wpt diff --git a/test/fixtures/wpt/WebCryptoAPI/META.yml b/test/fixtures/wpt/WebCryptoAPI/META.yml new file mode 100644 index 00000000000000..27a11a1fe47c39 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/META.yml @@ -0,0 +1,3 @@ +spec: https://w3c.github.io/webcrypto/ +suggested_reviewers: + - twiss diff --git a/test/fixtures/wpt/WebCryptoAPI/README.md b/test/fixtures/wpt/WebCryptoAPI/README.md new file mode 100644 index 00000000000000..5546cf2b6f2a1b --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/README.md @@ -0,0 +1 @@ +Directory for Crypto API tests diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js new file mode 100644 index 00000000000000..37e3eb4324200c --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js @@ -0,0 +1,9 @@ +// META: title=WebCryptoAPI: deriveBits() Using ECDH +// META: script=ecdh_bits.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js new file mode 100644 index 00000000000000..5cc7193aebd794 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.js @@ -0,0 +1,268 @@ + +function define_tests() { + // May want to test prefixed implementations. + var subtle = self.crypto.subtle; + + var pkcs8 = { + "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), + "P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 15, 247, 79, 232, 241, 202, 175, 97, 92, 206, 241, 29, 217, 53, 114, 87, 98, 217, 216, 65, 236, 186, 185, 94, 170, 38, 68, 123, 52, 100, 245, 113, 161, 68, 3, 66, 0, 4, 140, 96, 11, 44, 102, 25, 45, 97, 158, 39, 210, 37, 107, 59, 151, 118, 178, 141, 30, 5, 246, 13, 234, 189, 98, 174, 123, 154, 211, 157, 224, 217, 59, 4, 102, 109, 199, 119, 14, 126, 207, 13, 211, 203, 203, 211, 110, 221, 107, 94, 220, 153, 81, 7, 55, 161, 237, 104, 46, 205, 112, 244, 10, 47]), + "P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 248, 113, 165, 102, 101, 137, 193, 74, 87, 71, 38, 62, 248, 91, 49, 156, 192, 35, 219, 110, 53, 103, 108, 61, 120, 30, 239, 139, 5, 95, 207, 190, 134, 250, 13, 6, 208, 86, 181, 25, 95, 177, 50, 58, 248, 222, 37, 179, 161, 100, 3, 98, 0, 4, 241, 25, 101, 223, 125, 212, 89, 77, 4, 25, 197, 8, 100, 130, 163, 184, 38, 185, 121, 127, 155, 224, 189, 13, 16, 156, 158, 30, 153, 137, 193, 185, 169, 43, 143, 38, 159, 152, 225, 122, 209, 132, 186, 115, 193, 247, 151, 98, 175, 69, 175, 129, 65, 96, 38, 66, 218, 39, 26, 107, 176, 255, 235, 12, 180, 71, 143, 207, 112, 126, 102, 26, 166, 214, 205, 245, 21, 73, 200, 140, 63, 19, 11, 233, 232, 32, 31, 111, 106, 9, 244, 24, 90, 175, 149, 196]) + }; + + var spki = { + "P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 238, 105, 249, 71, 21, 215, 1, 233, 226, 1, 19, 51, 212, 244, 249, 108, 186, 125, 145, 248, 139, 17, 43, 175, 117, 207, 9, 204, 31, 138, 202, 151, 97, 141, 169, 56, 152, 34, 210, 155, 111, 233, 153, 106, 97, 32, 62, 247, 82, 183, 113, 232, 149, 143, 196, 103, 123, 179, 119, 133, 101, 171, 96, 214, 237, 0, 222, 171, 103, 97, 137, 91, 147, 94, 58, 211, 37, 251, 133, 73, 229, 111, 19, 120, 106, 167, 63, 136, 162, 236, 254, 64, 147, 52, 115, 216, 174, 242, 64, 196, 223, 215, 213, 6, 242, 44, 221, 14, 85, 85, 143, 63, 191, 5, 235, 247, 239, 239, 122, 114, 215, 143, 70, 70, 155, 132, 72, 242, 110, 39, 18]), + "P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]), + "P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 145, 130, 45, 194, 175, 89, 193, 143, 91, 103, 248, 13, 246, 26, 38, 3, 194, 168, 240, 179, 192, 175, 130, 45, 99, 194, 121, 112, 26, 130, 69, 96, 64, 68, 1, 221, 233, 165, 110, 229, 39, 87, 234, 139, 199, 72, 212, 200, 43, 83, 55, 180, 141, 123, 101, 88, 58, 61, 87, 36, 56, 136, 0, 54, 186, 198, 115, 15, 66, 202, 82, 120, 150, 107, 213, 242, 30, 134, 226, 29, 48, 197, 166, 208, 70, 62, 197, 19, 221, 80, 159, 252, 220, 175, 31, 245]) + }; + + var sizes = { + "P-521": 66, + "P-256": 32, + "P-384": 48 + }; + + var derivations = { + "P-521": new Uint8Array([0, 156, 43, 206, 87, 190, 128, 173, 171, 59, 7, 56, 91, 142, 89, 144, 235, 125, 111, 222, 189, 176, 27, 243, 83, 113, 164, 246, 7, 94, 157, 40, 138, 193, 42, 109, 254, 3, 170, 87, 67, 188, 129, 112, 157, 73, 168, 34, 148, 2, 25, 182, 75, 118, 138, 205, 82, 15, 161, 54, 142, 160, 175, 141, 71, 93]), + "P-256": new Uint8Array([14, 143, 60, 77, 177, 178, 162, 131, 115, 90, 0, 220, 87, 31, 26, 232, 151, 28, 227, 35, 250, 17, 131, 137, 203, 95, 65, 196, 59, 61, 181, 161]), + "P-384": new Uint8Array([224, 189, 107, 206, 10, 239, 140, 164, 136, 56, 166, 226, 252, 197, 126, 103, 185, 197, 232, 134, 12, 95, 11, 233, 218, 190, 197, 62, 69, 78, 24, 160, 161, 116, 196, 136, 136, 162, 100, 136, 17, 91, 45, 201, 241, 223, 165, 45]) + }; + + return importKeys(pkcs8, spki, sizes) + .then(function(results) { + publicKeys = results.publicKeys; + privateKeys = results.privateKeys; + ecdsaKeyPairs = results.ecdsaKeyPairs; + noDeriveBitsKeys = results.noDeriveBitsKeys; + + Object.keys(sizes).forEach(function(namedCurve) { + // Basic success case + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[namedCurve]), "Derived correct bits"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " good parameters"); + + // Case insensitivity check + promise_test(function(test) { + return subtle.deriveBits({name: "EcDh", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[namedCurve]), "Derived correct bits"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " mixed case parameters"); + + // Null length + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], null) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[namedCurve]), "Derived correct bits"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " with null length"); + + // Shorter than entire derivation per algorithm + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] - 32) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[namedCurve], 8 * sizes[namedCurve] - 32), "Derived correct bits"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " short result"); + + // Non-multiple of 8 + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] - 11) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[namedCurve], 8 * sizes[namedCurve] - 11), "Derived correct bits"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " non-multiple of 8 bits"); + + // Errors to test: + + // - missing public property TypeError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH"}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with TypeError"); + }, function(err) { + assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " missing public curve"); + + // - Non CryptoKey public property TypeError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: {message: "Not a CryptoKey"}}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with TypeError"); + }, function(err) { + assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property of algorithm is not a CryptoKey"); + + // - wrong named curve + promise_test(function(test) { + publicKey = publicKeys["P-256"]; + if (namedCurve === "P-256") { + publicKey = publicKeys["P-384"]; + } + return subtle.deriveBits({name: "ECDH", public: publicKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " mismatched curves"); + + // - not ECDH public property InvalidAccessError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: ecdsaKeyPairs[namedCurve].publicKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property of algorithm is not an ECDSA public key"); + + // - No deriveBits usage in baseKey InvalidAccessError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, noDeriveBitsKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " no deriveBits usage for base key"); + + // - Use public key for baseKey InvalidAccessError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, publicKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " base key is not a private key"); + + // - Use private key for public property InvalidAccessError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: privateKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property value is a private key"); + + // - Use secret key for public property InvalidAccessError + promise_test(function(test) { + return subtle.generateKey({name: "AES-CBC", length: 128}, true, ["encrypt", "decrypt"]) + .then(function(secretKey) { + subtle.deriveBits({name: "ECDH", public: secretKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }); + }, namedCurve + " public property value is a secret key"); + + // - Length greater than 256, 384, 521 for particular curves OperationError + promise_test(function(test) { + return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] + 8) + .then(function(derivation) { + assert_unreached("deriveBits succeeded but should have failed with OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " asking for too many bits"); + }); + }); + + function importKeys(pkcs8, spki, sizes) { + var privateKeys = {}; + var publicKeys = {}; + var ecdsaKeyPairs = {}; + var noDeriveBitsKeys = {}; + + var promises = []; + Object.keys(pkcs8).forEach(function(namedCurve) { + var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, ["deriveBits", "deriveKey"]) + .then(function(key) { + privateKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(pkcs8).forEach(function(namedCurve) { + var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, ["deriveKey"]) + .then(function(key) { + noDeriveBitsKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(spki).forEach(function(namedCurve) { + var operation = subtle.importKey("spki", spki[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, []) + .then(function(key) { + publicKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(sizes).forEach(function(namedCurve) { + var operation = subtle.generateKey({name: "ECDSA", namedCurve: namedCurve}, false, ["sign", "verify"]) + .then(function(keyPair) { + ecdsaKeyPairs[namedCurve] = keyPair; + }); + promises.push(operation); + }); + + return Promise.all(promises) + .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveBitsKeys: noDeriveBitsKeys}}); + } + + // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is + // omitted, the two values must be the same length and have the same contents + // in every byte. If bitCount is included, only that leading number of bits + // have to match. + function equalBuffers(a, b, bitCount) { + var remainder; + + if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + var length = a.byteLength; + if (typeof bitCount !== "undefined") { + length = Math.floor(bitCount / 8); + } + + for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); + } + + return true; + } + +} diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js new file mode 100644 index 00000000000000..d8235fce5a7412 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js @@ -0,0 +1,9 @@ +// META: title=WebCryptoAPI: deriveKey() Using ECDH +// META: script=ecdh_keys.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js new file mode 100644 index 00000000000000..99008e0cbbe09e --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/ecdh_keys.js @@ -0,0 +1,237 @@ + +function define_tests() { + // May want to test prefixed implementations. + var subtle = self.crypto.subtle; + + var pkcs8 = { + "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), + "P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 15, 247, 79, 232, 241, 202, 175, 97, 92, 206, 241, 29, 217, 53, 114, 87, 98, 217, 216, 65, 236, 186, 185, 94, 170, 38, 68, 123, 52, 100, 245, 113, 161, 68, 3, 66, 0, 4, 140, 96, 11, 44, 102, 25, 45, 97, 158, 39, 210, 37, 107, 59, 151, 118, 178, 141, 30, 5, 246, 13, 234, 189, 98, 174, 123, 154, 211, 157, 224, 217, 59, 4, 102, 109, 199, 119, 14, 126, 207, 13, 211, 203, 203, 211, 110, 221, 107, 94, 220, 153, 81, 7, 55, 161, 237, 104, 46, 205, 112, 244, 10, 47]), + "P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 248, 113, 165, 102, 101, 137, 193, 74, 87, 71, 38, 62, 248, 91, 49, 156, 192, 35, 219, 110, 53, 103, 108, 61, 120, 30, 239, 139, 5, 95, 207, 190, 134, 250, 13, 6, 208, 86, 181, 25, 95, 177, 50, 58, 248, 222, 37, 179, 161, 100, 3, 98, 0, 4, 241, 25, 101, 223, 125, 212, 89, 77, 4, 25, 197, 8, 100, 130, 163, 184, 38, 185, 121, 127, 155, 224, 189, 13, 16, 156, 158, 30, 153, 137, 193, 185, 169, 43, 143, 38, 159, 152, 225, 122, 209, 132, 186, 115, 193, 247, 151, 98, 175, 69, 175, 129, 65, 96, 38, 66, 218, 39, 26, 107, 176, 255, 235, 12, 180, 71, 143, 207, 112, 126, 102, 26, 166, 214, 205, 245, 21, 73, 200, 140, 63, 19, 11, 233, 232, 32, 31, 111, 106, 9, 244, 24, 90, 175, 149, 196]) + }; + + var spki = { + "P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 238, 105, 249, 71, 21, 215, 1, 233, 226, 1, 19, 51, 212, 244, 249, 108, 186, 125, 145, 248, 139, 17, 43, 175, 117, 207, 9, 204, 31, 138, 202, 151, 97, 141, 169, 56, 152, 34, 210, 155, 111, 233, 153, 106, 97, 32, 62, 247, 82, 183, 113, 232, 149, 143, 196, 103, 123, 179, 119, 133, 101, 171, 96, 214, 237, 0, 222, 171, 103, 97, 137, 91, 147, 94, 58, 211, 37, 251, 133, 73, 229, 111, 19, 120, 106, 167, 63, 136, 162, 236, 254, 64, 147, 52, 115, 216, 174, 242, 64, 196, 223, 215, 213, 6, 242, 44, 221, 14, 85, 85, 143, 63, 191, 5, 235, 247, 239, 239, 122, 114, 215, 143, 70, 70, 155, 132, 72, 242, 110, 39, 18]), + "P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]), + "P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 145, 130, 45, 194, 175, 89, 193, 143, 91, 103, 248, 13, 246, 26, 38, 3, 194, 168, 240, 179, 192, 175, 130, 45, 99, 194, 121, 112, 26, 130, 69, 96, 64, 68, 1, 221, 233, 165, 110, 229, 39, 87, 234, 139, 199, 72, 212, 200, 43, 83, 55, 180, 141, 123, 101, 88, 58, 61, 87, 36, 56, 136, 0, 54, 186, 198, 115, 15, 66, 202, 82, 120, 150, 107, 213, 242, 30, 134, 226, 29, 48, 197, 166, 208, 70, 62, 197, 19, 221, 80, 159, 252, 220, 175, 31, 245]) + }; + + var sizes = { + "P-521": 66, + "P-256": 32, + "P-384": 48 + }; + + var derivations = { + "P-521": new Uint8Array([0, 156, 43, 206, 87, 190, 128, 173, 171, 59, 7, 56, 91, 142, 89, 144, 235, 125, 111, 222, 189, 176, 27, 243, 83, 113, 164, 246, 7, 94, 157, 40, 138, 193, 42, 109, 254, 3, 170, 87, 67, 188, 129, 112, 157, 73, 168, 34, 148, 2, 25, 182, 75, 118, 138, 205, 82, 15, 161, 54, 142, 160, 175, 141, 71, 93]), + "P-256": new Uint8Array([14, 143, 60, 77, 177, 178, 162, 131, 115, 90, 0, 220, 87, 31, 26, 232, 151, 28, 227, 35, 250, 17, 131, 137, 203, 95, 65, 196, 59, 61, 181, 161]), + "P-384": new Uint8Array([224, 189, 107, 206, 10, 239, 140, 164, 136, 56, 166, 226, 252, 197, 126, 103, 185, 197, 232, 134, 12, 95, 11, 233, 218, 190, 197, 62, 69, 78, 24, 160, 161, 116, 196, 136, 136, 162, 100, 136, 17, 91, 45, 201, 241, 223, 165, 45]) + }; + + return importKeys(pkcs8, spki, sizes) + .then(function(results) { + publicKeys = results.publicKeys; + privateKeys = results.privateKeys; + ecdsaKeyPairs = results.ecdsaKeyPairs; + noDeriveKeyKeys = results.noDeriveKeyKeys; + + Object.keys(sizes).forEach(function(namedCurve) { + // Basic success case + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_true(equalBuffers(exportedKey, derivations[namedCurve], 8 * exportedKey.length), "Derived correct key"); + }, function(err) { + assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " good parameters"); + + // Case insensitivity check + promise_test(function(test) { + return subtle.deriveKey({name: "EcDh", public: publicKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_true(equalBuffers(exportedKey, derivations[namedCurve], 8 * exportedKey.length), "Derived correct key"); + }, function(err) { + assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); + }); + }, namedCurve + " mixed case parameters"); + // Errors to test: + + // - missing public property TypeError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH"}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with TypeError"); + }, function(err) { + assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " missing public curve"); + + // - Non CryptoKey public property TypeError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: {message: "Not a CryptoKey"}}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with TypeError"); + }, function(err) { + assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property of algorithm is not a CryptoKey"); + + // - wrong named curve + promise_test(function(test) { + publicKey = publicKeys["P-256"]; + if (namedCurve === "P-256") { + publicKey = publicKeys["P-384"]; + } + return subtle.deriveKey({name: "ECDH", public: publicKey}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " mismatched curves"); + + // - not ECDH public property InvalidAccessError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: ecdsaKeyPairs[namedCurve].publicKey}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property of algorithm is not an ECDSA public key"); + + // - No deriveKey usage in baseKey InvalidAccessError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, noDeriveKeyKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " no deriveKey usage for base key"); + + // - Use public key for baseKey InvalidAccessError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, publicKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " base key is not a private key"); + + // - Use private key for public property InvalidAccessError + promise_test(function(test) { + return subtle.deriveKey({name: "ECDH", public: privateKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, namedCurve + " public property value is a private key"); + + // - Use secret key for public property InvalidAccessError + promise_test(function(test) { + return subtle.generateKey({name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + .then(function(secretKey) { + subtle.deriveKey({name: "ECDH", public: secretKey}, privateKeys[namedCurve], {name: "AES-CBC", length: 256}, true, ["sign", "verify"]) + .then(function(key) {return crypto.subtle.exportKey("raw", key);}) + .then(function(exportedKey) { + assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }); + }, namedCurve + " public property value is a secret key"); + }); + }); + + function importKeys(pkcs8, spki, sizes) { + var privateKeys = {}; + var publicKeys = {}; + var ecdsaKeyPairs = {}; + var noDeriveKeyKeys = {}; + + var promises = []; + Object.keys(pkcs8).forEach(function(namedCurve) { + var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, ["deriveBits", "deriveKey"]) + .then(function(key) { + privateKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(pkcs8).forEach(function(namedCurve) { + var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, ["deriveBits"]) + .then(function(key) { + noDeriveKeyKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(spki).forEach(function(namedCurve) { + var operation = subtle.importKey("spki", spki[namedCurve], + {name: "ECDH", namedCurve: namedCurve}, + false, []) + .then(function(key) { + publicKeys[namedCurve] = key; + }); + promises.push(operation); + }); + Object.keys(sizes).forEach(function(namedCurve) { + var operation = subtle.generateKey({name: "ECDSA", namedCurve: namedCurve}, false, ["sign", "verify"]) + .then(function(keyPair) { + ecdsaKeyPairs[namedCurve] = keyPair; + }); + promises.push(operation); + }); + + return Promise.all(promises) + .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveKeyKeys: noDeriveKeyKeys}}); + } + + // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is + // omitted, the two values must be the same length and have the same contents + // in every byte. If bitCount is included, only that leading number of bits + // have to match. + function equalBuffers(a, b, bitCount) { + var remainder; + + if (typeof bitCount === "undefined" && a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + var length = a.byteLength; + if (typeof bitCount !== "undefined") { + length = Math.floor(bitCount / 8); + } + + for (var i=0; i> (8 - remainder) === bBytes[length] >> (8 - remainder); + } + + return true; + } + +} diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js new file mode 100644 index 00000000000000..02492c3741c7d1 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js @@ -0,0 +1,15 @@ +// META: title=WebCryptoAPI: deriveBits() and deriveKey() Using HKDF +// META: variant=?1-1000 +// META: variant=?1001-2000 +// META: variant=?2001-3000 +// META: variant=?3001-last +// META: script=/common/subset-tests.js +// META: script=hkdf_vectors.js +// META: script=hkdf.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js new file mode 100644 index 00000000000000..2bb58533473eb9 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/hkdf.js @@ -0,0 +1,305 @@ + +function define_tests() { + // May want to test prefixed implementations. + var subtle = self.crypto.subtle; + + // hkdf2_vectors sets up test data with the correct derivations for each + // test case. + var testData = getTestData(); + var derivedKeys = testData.derivedKeys; + var salts = testData.salts; + var derivations = testData.derivations; + var infos = testData.infos; + + // What kinds of keys can be created with deriveKey? The following: + var derivedKeyTypes = testData.derivedKeyTypes; + + return setUpBaseKeys(derivedKeys) + .then(function(allKeys) { + // We get several kinds of base keys. Normal ones that can be used for + // derivation operations, ones that lack the deriveBits usage, ones + // that lack the deriveKeys usage, and one key that is for the wrong + // algorithm (not HKDF in this case). + var baseKeys = allKeys.baseKeys; + var noBits = allKeys.noBits; + var noKey = allKeys.noKey; + var wrongKey = allKeys.wrongKey; + + // Test each combination of derivedKey size, salt size, hash function, + // and number of iterations. The derivations object is structured in + // that way, so navigate it to run tests and compare with correct results. + Object.keys(derivations).forEach(function(derivedKeySize) { + Object.keys(derivations[derivedKeySize]).forEach(function(saltSize) { + Object.keys(derivations[derivedKeySize][saltSize]).forEach(function(hashName) { + Object.keys(derivations[derivedKeySize][saltSize][hashName]).forEach(function(infoSize) { + var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + hashName + ", with " + infoSize + " info"; + var algorithm = {name: "HKDF", salt: salts[saltSize], info: infos[infoSize], hash: hashName}; + + // Check for correct deriveBits result + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 256) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[derivedKeySize][saltSize][hashName][infoSize]), "Derived correct key"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, testName); + + // 0 length (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived correctly empty key"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with 0 length correctly threw OperationError: " + err.message); + }); + }, testName + " with 0 length"); + + // Check for correct deriveKey results for every kind of + // key that can be created by the deriveKeys operation. + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + testName += " using " + derivedKeySize + " derivedKey, " + saltSize + " salt, " + hashName + ", with " + infoSize + " info"; + + // Test the particular key derivation. + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + // Need to export the key to see that the correct bits were set. + return subtle.exportKey("raw", key) + .then(function(buffer) { + assert_true(equalBuffers(buffer, derivations[derivedKeySize][saltSize][hashName][infoSize].slice(0, derivedKeyType.algorithm.length/8)), "Exported key matches correct value"); + }, function(err) { + assert_unreached("Exporting derived key failed with error " + err.name + ": " + err.message); + }); + }, function(err) { + assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); + + }); + }, testName); + + // Test various error conditions for deriveKey: + + // - illegal name for hash algorithm (NotSupportedError) + var badHash = hashName.substring(0, 3) + hashName.substring(4); + subsetTest(promise_test, function(test) { + var badAlgorithm = {name: "HKDF", salt: salts[saltSize], hash: badHash, info: algorithm.info}; + return subtle.deriveKey(badAlgorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveKey with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with bad hash name " + badHash); + + // - baseKey usages missing "deriveKey" (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, noKey[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("missing deriveKey usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with missing deriveKey usage correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with missing deriveKey usage"); + + // - baseKey algorithm does not match HKDF (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, wrongKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with wrong (ECDH) key"); + + }); + + // Test various error conditions for deriveBits below: + + // missing salt (TypeError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "HKDF", info: infos[infoSize], hash: hashName}, baseKeys[derivedKeySize], 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived even with missing salt"); + }, function(err) { + assert_equals(err.name, "TypeError", "deriveBits missing salt correctly threw OperationError: " + err.message); + }); + }, testName + " with missing salt"); + + // missing info (TypeError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "HKDF", salt: salts[saltSize], hash: hashName}, baseKeys[derivedKeySize], 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived even with missing info"); + }, function(err) { + assert_equals(err.name, "TypeError", "deriveBits missing info correctly threw OperationError: " + err.message); + }); + }, testName + " with missing info"); + + // length null (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], null) + .then(function(derivation) { + assert_unreached("null length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with null length correctly threw OperationError: " + err.message); + }); + }, testName + " with null length"); + + // length not multiple of 8 (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 44) + .then(function(derivation) { + assert_unreached("non-multiple of 8 length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with non-multiple of 8 length correctly threw OperationError: " + err.message); + }); + }, testName + " with non-multiple of 8 length"); + + // - illegal name for hash algorithm (NotSupportedError) + var badHash = hashName.substring(0, 3) + hashName.substring(4); + subsetTest(promise_test, function(test) { + var badAlgorithm = {name: "HKDF", salt: salts[saltSize], hash: badHash, info: algorithm.info}; + return subtle.deriveBits(badAlgorithm, baseKeys[derivedKeySize], 256) + .then(function(derivation) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with bad hash name " + badHash); + + // - baseKey usages missing "deriveBits" (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, noBits[derivedKeySize], 256) + .then(function(derivation) { + assert_unreached("missing deriveBits usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with missing deriveBits usage correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with missing deriveBits usage"); + + // - baseKey algorithm does not match HKDF (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, wrongKey, 256) + .then(function(derivation) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with wrong (ECDH) key"); + }); + }); + + // - legal algorithm name but not digest one (e.g., PBKDF2) (NotSupportedError) + var nonDigestHash = "PBKDF2"; + Object.keys(infos).forEach(function(infoSize) { + var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + nonDigestHash + ", with " + infoSize + " info"; + var algorithm = {name: "HKDF", salt: salts[saltSize], hash: nonDigestHash}; + if (infoSize !== "missing") { + algorithm.info = infos[infoSize]; + } + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 256) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with non-digest algorithm " + nonDigestHash); + + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + testName += " using " + derivedKeySize + " derivedKey, " + saltSize + " salt, " + nonDigestHash + ", with " + infoSize + " info"; + + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "derivekey with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, testName); + }); + + }); + + }); + }); + }); + + // Deriving bits and keys requires starting with a base key, which is created + // by importing a derivedKey. setUpBaseKeys returns a promise that yields the + // necessary base keys. + function setUpBaseKeys(derivedKeys) { + var promises = []; + + var baseKeys = {}; + var noBits = {}; + var noKey = {}; + var wrongKey = null; + + Object.keys(derivedKeys).forEach(function(derivedKeySize) { + var promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + baseKeys[derivedKeySize] = baseKey; + }, function(err) { + baseKeys[derivedKeySize] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveBits"]) + .then(function(baseKey) { + noKey[derivedKeySize] = baseKey; + }, function(err) { + noKey[derivedKeySize] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveKey"]) + .then(function(baseKey) { + noBits[derivedKeySize] = baseKey; + }, function(err) { + noBits[derivedKeySize] = null; + }); + promises.push(promise); + }); + + var promise = subtle.generateKey({name: "ECDH", namedCurve: "P-256"}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + wrongKey = baseKey.privateKey; + }, function(err) { + wrongKey = null; + }); + promises.push(promise); + + + return Promise.all(promises).then(function() { + return {baseKeys: baseKeys, noBits: noBits, noKey: noKey, wrongKey: wrongKey}; + }); + } + + function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i=0; in + + // Variations to test: + // - empty, short, and fairly long derivedKey + // - empty, short, and fairly long salt + // - SHA-1, SHA-256, SHA-384, SHA-512 hash + // - 1, 1000, and 100000 million iterations + + // Test cases to generate: 3 * 3 * 4 * 3 = 108 + + // Error conditions to test: + // - length null (OperationError) + // - length not a multiple of 8 (OperationError) + // - illegal name for hash algorithm (NotSupportedError) + // - legal algorithm name but not digest one (e.g., AES-CBC) (NotSupportedError) + // - baseKey usages missing "deriveBits" (InvalidAccessError) + // - baseKey algorithm does not match HKDF (InvalidAccessError) + // - 0 iterations + + var derivedKeyTypes = [ + {algorithm: {name: "AES-CBC", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CBC", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CBC", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-KW", length: 128}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "AES-KW", length: 192}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "AES-KW", length: 256}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "HMAC", hash: "SHA-1", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-256", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-384", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-512", length: 256}, usages: ["sign", "verify"]} + ]; + + var derivedKeys = { + "short": new Uint8Array([80, 64, 115, 115, 119, 48, 114, 100]), + "long": new Uint8Array([85, 115, 101, 114, 115, 32, 115, 104, 111, 117, 108, 100, 32, 112, 105, 99, 107, 32, 108, 111, 110, 103, 32, 112, 97, 115, 115, 112, 104, 114, 97, 115, 101, 115, 32, 40, 110, 111, 116, 32, 117, 115, 101, 32, 115, 104, 111, 114, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100, 115, 41, 33]), + "empty": new Uint8Array([]) + }; + + var salts = { + "normal": new Uint8Array([83, 111, 100, 105, 117, 109, 32, 67, 104, 108, 111, 114, 105, 100, 101, 32, 99, 111, 109, 112, 111, 117, 110, 100]), + "empty": new Uint8Array([]) + }; + + var infos = { + "normal": new Uint8Array([72, 75, 68, 70, 32, 101, 120, 116, 114, 97, 32, 105, 110, 102, 111]), + "empty": new Uint8Array([]) + }; + + var derivations = { + "short": { + "normal": { + "SHA-384": { + "normal": new Uint8Array([25, 186, 116, 54, 142, 107, 153, 51, 144, 242, 127, 233, 167, 208, 43, 195, 56, 23, 63, 114, 190, 113, 161, 159, 199, 68, 252, 219, 63, 212, 184, 75]), + "empty": new Uint8Array([151, 96, 31, 78, 12, 83, 165, 211, 243, 162, 129, 0, 153, 188, 104, 32, 236, 80, 8, 52, 52, 118, 155, 89, 252, 36, 164, 23, 169, 84, 55, 52]) + }, + "SHA-512": { + "normal": new Uint8Array([75, 189, 109, 178, 67, 95, 182, 150, 21, 127, 96, 137, 201, 119, 195, 199, 63, 62, 172, 94, 243, 221, 107, 170, 230, 4, 203, 83, 191, 187, 21, 62]), + "empty": new Uint8Array([47, 49, 87, 231, 254, 12, 16, 176, 18, 152, 200, 240, 136, 106, 144, 237, 207, 128, 171, 222, 245, 219, 193, 223, 43, 20, 130, 83, 43, 82, 185, 52]) + }, + "SHA-1": { + "normal": new Uint8Array([5, 173, 34, 237, 33, 56, 201, 96, 14, 77, 158, 39, 37, 222, 211, 1, 245, 210, 135, 251, 251, 87, 2, 249, 153, 188, 101, 54, 211, 237, 239, 152]), + "empty": new Uint8Array([213, 27, 111, 183, 229, 153, 202, 48, 197, 238, 38, 69, 147, 228, 184, 95, 34, 32, 199, 195, 171, 0, 49, 87, 191, 248, 203, 79, 54, 156, 117, 96]) + }, + "SHA-256": { + "normal": new Uint8Array([42, 245, 144, 30, 40, 132, 156, 40, 68, 56, 87, 56, 106, 161, 172, 59, 177, 39, 233, 38, 49, 193, 192, 81, 72, 45, 102, 144, 148, 23, 114, 180]), + "empty": new Uint8Array([158, 75, 113, 144, 51, 116, 33, 1, 233, 15, 26, 214, 30, 47, 243, 180, 37, 104, 99, 102, 114, 150, 215, 67, 137, 241, 240, 42, 242, 196, 230, 166]) + } + }, + "empty": { + "SHA-384": { + "normal": new Uint8Array([251, 72, 47, 242, 44, 79, 141, 70, 108, 77, 254, 110, 41, 242, 204, 46, 205, 171, 245, 136, 67, 40, 251, 240, 138, 115, 143, 217, 69, 241, 102, 203]), + "empty": new Uint8Array([30, 2, 60, 23, 179, 64, 83, 60, 234, 239, 57, 35, 12, 184, 179, 187, 219, 246, 99, 161, 61, 96, 117, 208, 221, 50, 108, 4, 148, 120, 251, 165]) + }, + "SHA-512": { + "normal": new Uint8Array([241, 123, 91, 220, 216, 215, 211, 212, 96, 16, 54, 161, 148, 54, 49, 125, 22, 68, 249, 164, 224, 149, 110, 252, 14, 55, 43, 131, 172, 218, 207, 219]), + "empty": new Uint8Array([199, 180, 116, 148, 47, 49, 248, 63, 175, 93, 20, 115, 24, 2, 177, 189, 73, 71, 133, 73, 203, 58, 143, 61, 191, 237, 196, 211, 32, 156, 245, 182]) + }, + "SHA-1": { + "normal": new Uint8Array([193, 38, 241, 230, 242, 90, 157, 228, 44, 247, 212, 39, 5, 154, 82, 237, 150, 1, 242, 154, 88, 21, 203, 251, 198, 75, 199, 246, 104, 198, 163, 65]), + "empty": new Uint8Array([50, 21, 195, 240, 141, 231, 5, 73, 176, 81, 183, 3, 55, 69, 168, 24, 79, 140, 186, 166, 177, 115, 83, 48, 210, 188, 182, 177, 111, 70, 66, 239]) + }, + "SHA-256": { + "normal": new Uint8Array([115, 60, 139, 107, 207, 172, 135, 92, 127, 8, 152, 42, 110, 63, 251, 86, 10, 206, 166, 241, 101, 71, 110, 184, 52, 96, 185, 53, 62, 212, 29, 254]), + "empty": new Uint8Array([200, 225, 39, 116, 19, 83, 5, 201, 20, 127, 44, 196, 118, 110, 94, 173, 37, 216, 244, 87, 185, 161, 149, 61, 82, 103, 115, 97, 206, 213, 88, 251]) + } + } + }, + "long": { + "normal": { + "SHA-384": { + "normal": new Uint8Array([249, 21, 113, 181, 33, 247, 238, 241, 62, 87, 58, 164, 99, 120, 101, 158, 243, 183, 243, 111, 253, 209, 187, 5, 93, 178, 205, 119, 210, 96, 196, 103]), + "empty": new Uint8Array([104, 175, 28, 44, 246, 185, 55, 13, 32, 84, 52, 71, 152, 189, 187, 24, 71, 204, 244, 7, 183, 101, 43, 121, 61, 209, 54, 212, 100, 14, 3, 72]) + }, + "SHA-512": { + "normal": new Uint8Array([113, 10, 174, 47, 223, 136, 158, 69, 254, 15, 185, 149, 178, 194, 107, 51, 235, 152, 134, 80, 236, 15, 174, 241, 103, 2, 138, 122, 108, 203, 54, 56]), + "empty": new Uint8Array([229, 222, 86, 128, 129, 199, 30, 86, 39, 80, 130, 152, 113, 195, 66, 117, 129, 4, 118, 94, 214, 243, 6, 240, 97, 60, 157, 75, 179, 54, 242, 170]) + }, + "SHA-1": { + "normal": new Uint8Array([127, 149, 126, 220, 188, 227, 203, 11, 112, 86, 110, 30, 182, 14, 253, 30, 64, 90, 19, 48, 76, 102, 29, 54, 99, 119, 129, 9, 191, 6, 137, 156]), + "empty": new Uint8Array([48, 98, 243, 207, 26, 115, 11, 156, 239, 81, 240, 44, 29, 250, 200, 94, 217, 30, 75, 0, 101, 235, 80, 202, 159, 216, 176, 16, 126, 114, 135, 51]) + }, + "SHA-256": { + "normal": new Uint8Array([49, 183, 214, 133, 48, 168, 99, 231, 23, 192, 129, 202, 105, 23, 182, 134, 80, 179, 221, 154, 41, 243, 6, 6, 226, 202, 209, 153, 190, 193, 77, 19]), + "empty": new Uint8Array([229, 121, 209, 249, 231, 240, 142, 111, 153, 15, 252, 252, 206, 30, 210, 1, 197, 227, 126, 98, 205, 246, 6, 240, 186, 74, 202, 128, 66, 127, 188, 68]) + } + }, + "empty": { + "SHA-384": { + "normal": new Uint8Array([97, 158, 182, 249, 40, 115, 149, 187, 213, 237, 106, 103, 201, 104, 70, 90, 216, 43, 108, 85, 159, 60, 56, 182, 4, 187, 176, 143, 88, 50, 11, 3]), + "empty": new Uint8Array([255, 68, 123, 66, 61, 131, 254, 118, 131, 108, 50, 51, 114, 40, 181, 107, 91, 217, 191, 104, 213, 142, 125, 202, 75, 124, 202, 132, 42, 69, 225, 26]) + }, + "SHA-512": { + "normal": new Uint8Array([19, 62, 138, 127, 127, 244, 51, 105, 12, 200, 132, 50, 194, 163, 56, 194, 119, 229, 193, 55, 86, 255, 135, 143, 70, 117, 63, 230, 165, 100, 227, 229]), + "empty": new Uint8Array([222, 84, 247, 238, 200, 12, 156, 198, 109, 52, 159, 201, 135, 248, 13, 70, 29, 178, 239, 79, 244, 225, 133, 5, 210, 139, 216, 12, 180, 44, 125, 118]) + }, + "SHA-1": { + "normal": new Uint8Array([173, 185, 60, 219, 206, 121, 183, 213, 17, 89, 182, 192, 19, 26, 43, 98, 242, 56, 40, 210, 106, 205, 104, 94, 52, 192, 101, 53, 230, 247, 116, 150]), + "empty": new Uint8Array([71, 113, 13, 42, 117, 7, 224, 90, 29, 220, 200, 122, 124, 47, 144, 97, 119, 162, 102, 239, 185, 230, 34, 81, 12, 204, 179, 113, 60, 208, 141, 88]) + }, + "SHA-256": { + "normal": new Uint8Array([164, 1, 215, 201, 21, 138, 41, 229, 199, 25, 58, 185, 115, 15, 7, 72, 133, 28, 197, 186, 173, 180, 44, 173, 2, 75, 98, 144, 254, 33, 52, 54]), + "empty": new Uint8Array([180, 247, 231, 85, 118, 116, 213, 1, 203, 251, 192, 20, 138, 216, 0, 192, 117, 1, 137, 254, 41, 90, 42, 202, 94, 27, 244, 18, 44, 133, 237, 249]) + } + } + }, + "empty": { + "normal": { + "SHA-384": { + "normal": new Uint8Array([106, 134, 50, 228, 134, 137, 157, 194, 100, 241, 161, 249, 32, 89, 63, 40, 128, 128, 78, 14, 26, 218, 207, 148, 235, 78, 213, 229, 248, 61, 13, 18]), + "empty": new Uint8Array([234, 80, 18, 254, 181, 135, 81, 213, 188, 142, 182, 78, 13, 234, 205, 89, 126, 215, 16, 201, 243, 82, 88, 174, 107, 154, 8, 122, 237, 7, 37, 174]) + }, + "SHA-512": { + "normal": new Uint8Array([199, 151, 225, 209, 242, 202, 183, 242, 138, 95, 67, 69, 92, 16, 89, 127, 148, 51, 133, 237, 251, 66, 140, 254, 43, 152, 190, 212, 169, 85, 215, 161]), + "empty": new Uint8Array([224, 140, 220, 196, 197, 166, 170, 121, 157, 134, 188, 3, 169, 84, 117, 39, 110, 187, 128, 29, 154, 222, 1, 110, 20, 168, 250, 91, 100, 5, 22, 81]) + }, + "SHA-1": { + "normal": new Uint8Array([171, 103, 158, 103, 188, 180, 48, 95, 238, 66, 239, 148, 14, 80, 156, 221, 212, 6, 227, 73, 143, 133, 116, 24, 169, 121, 171, 57, 207, 49, 95, 81]), + "empty": new Uint8Array([254, 66, 33, 135, 24, 140, 134, 54, 211, 109, 170, 213, 142, 242, 132, 49, 164, 51, 191, 15, 239, 114, 209, 202, 231, 53, 160, 75, 219, 190, 185, 211]) + }, + "SHA-256": { + "normal": new Uint8Array([223, 146, 185, 169, 250, 156, 1, 184, 152, 206, 234, 161, 49, 52, 131, 46, 49, 203, 28, 8, 29, 22, 165, 35, 92, 105, 216, 86, 81, 227, 23, 172]), + "empty": new Uint8Array([230, 13, 67, 43, 6, 238, 136, 157, 250, 183, 41, 154, 32, 236, 35, 105, 117, 49, 209, 25, 252, 247, 102, 208, 152, 141, 10, 203, 12, 0, 199, 247]) + } + }, + "empty": { + "SHA-384": { + "normal": new Uint8Array([234, 203, 157, 102, 112, 255, 59, 25, 4, 119, 154, 65, 145, 1, 177, 255, 170, 189, 109, 101, 16, 189, 80, 133, 104, 1, 116, 106, 135, 31, 123, 49]), + "empty": new Uint8Array([71, 12, 198, 83, 135, 202, 74, 16, 199, 166, 138, 59, 81, 72, 200, 229, 19, 218, 166, 49, 1, 0, 7, 57, 196, 198, 101, 155, 134, 17, 136, 132]) + }, + "SHA-512": { + "normal": new Uint8Array([87, 3, 145, 116, 241, 111, 84, 24, 168, 104, 86, 218, 235, 119, 246, 157, 75, 77, 80, 0, 51, 75, 109, 209, 244, 244, 179, 231, 179, 220, 185, 211]), + "empty": new Uint8Array([157, 115, 201, 142, 121, 30, 128, 235, 229, 180, 203, 69, 105, 58, 163, 47, 221, 68, 181, 250, 62, 218, 179, 236, 130, 249, 208, 244, 214, 105, 5, 226]) + }, + "SHA-1": { + "normal": new Uint8Array([161, 189, 216, 195, 50, 198, 70, 74, 75, 182, 162, 242, 49, 174, 201, 164, 68, 35, 126, 171, 224, 77, 47, 85, 242, 171, 37, 212, 12, 84, 235, 238]), + "empty": new Uint8Array([136, 95, 192, 41, 179, 34, 75, 137, 110, 9, 224, 187, 229, 235, 52, 126, 197, 158, 104, 39, 200, 232, 87, 179, 148, 245, 79, 244, 155, 136, 168, 246]) + }, + "SHA-256": { + "normal": new Uint8Array([183, 184, 110, 66, 42, 209, 200, 165, 113, 253, 165, 40, 218, 22, 160, 102, 244, 36, 134, 221, 64, 86, 121, 47, 217, 51, 98, 8, 142, 93, 212, 194]), + "empty": new Uint8Array([235, 112, 240, 29, 237, 233, 175, 175, 164, 73, 238, 225, 177, 40, 101, 4, 225, 246, 35, 136, 179, 247, 221, 79, 149, 102, 151, 176, 232, 40, 254, 24]) + } + } + } + }; + + return {derivedKeys: derivedKeys, salts: salts, derivations: derivations, derivedKeyTypes: derivedKeyTypes, infos: infos}; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js new file mode 100644 index 00000000000000..2efbe523f8cd7d --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js @@ -0,0 +1,21 @@ +// META: title=WebCryptoAPI: deriveBits() and deriveKey() Using PBKDF2 +// META: timeout=long +// META: variant=?1-1000 +// META: variant=?1001-2000 +// META: variant=?2001-3000 +// META: variant=?3001-4000 +// META: variant=?4001-5000 +// META: variant=?5001-6000 +// META: variant=?6001-7000 +// META: variant=?7001-8000 +// META: variant=?8001-last +// META: script=/common/subset-tests.js +// META: script=pbkdf2_vectors.js +// META: script=pbkdf2.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.js new file mode 100644 index 00000000000000..0403f382e1479c --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.js @@ -0,0 +1,302 @@ +function define_tests() { + // May want to test prefixed implementations. + var subtle = self.crypto.subtle; + + // pbkdf2_vectors sets up test data with the correct derivations for each + // test case. + var testData = getTestData(); + var passwords = testData.passwords; + var salts = testData.salts; + var derivations = testData.derivations; + + // What kinds of keys can be created with deriveKey? The following: + var derivedKeyTypes = testData.derivedKeyTypes; + + return setUpBaseKeys(passwords) + .then(function(allKeys) { + // We get several kinds of base keys. Normal ones that can be used for + // derivation operations, ones that lack the deriveBits usage, ones + // that lack the deriveKeys usage, and one key that is for the wrong + // algorithm (not PBKDF2 in this case). + var baseKeys = allKeys.baseKeys; + var noBits = allKeys.noBits; + var noKey = allKeys.noKey; + var wrongKey = allKeys.wrongKey; + + // Test each combination of password size, salt size, hash function, + // and number of iterations. The derivations object is structured in + // that way, so navigate it to run tests and compare with correct results. + Object.keys(derivations).forEach(function(passwordSize) { + Object.keys(derivations[passwordSize]).forEach(function(saltSize) { + Object.keys(derivations[passwordSize][saltSize]).forEach(function(hashName) { + Object.keys(derivations[passwordSize][saltSize][hashName]).forEach(function(iterations) { + var testName = passwordSize + " password, " + saltSize + " salt, " + hashName + ", with " + iterations + " iterations"; + + // Check for correct deriveBits result + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) + .then(function(derivation) { + assert_true(equalBuffers(derivation, derivations[passwordSize][saltSize][hashName][iterations]), "Derived correct key"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, testName); + + // Check for correct deriveKey results for every kind of + // key that can be created by the deriveKeys operation. + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + testName += " using " + passwordSize + " password, " + saltSize + " salt, " + hashName + ", with " + iterations + " iterations"; + + // Test the particular key derivation. + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + // Need to export the key to see that the correct bits were set. + return subtle.exportKey("raw", key) + .then(function(buffer) { + assert_true(equalBuffers(buffer, derivations[passwordSize][saltSize][hashName][iterations].slice(0, derivedKeyType.algorithm.length/8)), "Exported key matches correct value"); + }, function(err) { + assert_unreached("Exporting derived key failed with error " + err.name + ": " + err.message); + }); + }, function(err) { + assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); + + }); + }, testName); + + // Test various error conditions for deriveKey: + + // - illegal name for hash algorithm (NotSupportedError) + var badHash = hashName.substring(0, 3) + hashName.substring(4); + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: badHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveKey with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with bad hash name " + badHash); + + // - baseKey usages missing "deriveKey" (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, noKey[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("missing deriveKey usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with missing deriveKey usage correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with missing deriveKey usage"); + + // - baseKey algorithm does not match PBKDF2 (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, wrongKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with wrong (ECDH) key"); + + }); + + // Test various error conditions for deriveBits below: + // length null (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], null) + .then(function(derivation) { + assert_unreached("null length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with null length correctly threw OperationError: " + err.message); + }); + }, testName + " with null length"); + + // 0 length (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 0) + .then(function(derivation) { + assert_unreached("0 length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with 0 length correctly threw OperationError: " + err.message); + }); + }, testName + " with 0 length"); + + // length not multiple of 8 (OperationError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 44) + .then(function(derivation) { + assert_unreached("non-multiple of 8 length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with non-multiple of 8 length correctly threw OperationError: " + err.message); + }); + }, testName + " with non-multiple of 8 length"); + + // - illegal name for hash algorithm (NotSupportedError) + var badHash = hashName.substring(0, 3) + hashName.substring(4); + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: badHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) + .then(function(derivation) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with bad hash name " + badHash); + + // - baseKey usages missing "deriveBits" (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, noBits[passwordSize], 256) + .then(function(derivation) { + assert_unreached("missing deriveBits usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with missing deriveBits usage correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with missing deriveBits usage"); + + // - baseKey algorithm does not match PBKDF2 (InvalidAccessError) + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, wrongKey, 256) + .then(function(derivation) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with wrong (ECDH) key"); + }); + + // Check that 0 iterations throws proper error + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: 0}, baseKeys[passwordSize], 256) + .then(function(derivation) { + assert_unreached("0 iterations should have thrown an error"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with 0 iterations correctly threw OperationError: " + err.message); + }); + }, passwordSize + " password, " + saltSize + " salt, " + hashName + ", with 0 iterations"); + + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + testName += " using " + passwordSize + " password, " + saltSize + " salt, " + hashName + ", with 0 iterations"; + + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: 0}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(derivation) { + assert_unreached("0 iterations should have thrown an error"); + }, function(err) { + assert_equals(err.name, "OperationError", "derivekey with 0 iterations correctly threw OperationError: " + err.message); + }); + }, testName); + }); + }); + + // - legal algorithm name but not digest one (e.g., PBKDF2) (NotSupportedError) + var nonDigestHash = "PBKDF2"; + [1, 1000, 100000].forEach(function(iterations) { + var testName = passwordSize + " password, " + saltSize + " salt, " + nonDigestHash + ", with " + iterations + " iterations"; + + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: nonDigestHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with non-digest algorithm " + nonDigestHash); + + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + testName += " using " + passwordSize + " password, " + saltSize + " salt, " + nonDigestHash + ", with " + iterations + " iterations"; + + subsetTest(promise_test, function(test) { + return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: nonDigestHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "derivekey with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, testName); + }); + + }); + + }); + }); + }); + + // Deriving bits and keys requires starting with a base key, which is created + // by importing a password. setUpBaseKeys returns a promise that yields the + // necessary base keys. + function setUpBaseKeys(passwords) { + var promises = []; + + var baseKeys = {}; + var noBits = {}; + var noKey = {}; + var wrongKey = null; + + Object.keys(passwords).forEach(function(passwordSize) { + var promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + baseKeys[passwordSize] = baseKey; + }, function(err) { + baseKeys[passwordSize] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveBits"]) + .then(function(baseKey) { + noKey[passwordSize] = baseKey; + }, function(err) { + noKey[passwordSize] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveKey"]) + .then(function(baseKey) { + noBits[passwordSize] = baseKey; + }, function(err) { + noBits[passwordSize] = null; + }); + promises.push(promise); + }); + + var promise = subtle.generateKey({name: "ECDH", namedCurve: "P-256"}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + wrongKey = baseKey.privateKey; + }, function(err) { + wrongKey = null; + }); + promises.push(promise); + + + return Promise.all(promises).then(function() { + return {baseKeys: baseKeys, noBits: noBits, noKey: noKey, wrongKey: wrongKey}; + }); + } + + function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i=0; in + + // Variations to test: + // - empty, short, and fairly long password + // - empty, short, and fairly long salt + // - SHA-1, SHA-256, SHA-384, SHA-512 hash + // - 1, 1000, and 100000 million iterations + + // Test cases to generate: 3 * 3 * 4 * 3 = 108 + + // Error conditions to test: + // - length null (OperationError) + // - length not a multiple of 8 (OperationError) + // - illegal name for hash algorithm (NotSupportedError) + // - legal algorithm name but not digest one (e.g., AES-CBC) (NotSupportedError) + // - baseKey usages missing "deriveBits" (InvalidAccessError) + // - baseKey algorithm does not match PBKDF2 (InvalidAccessError) + // - 0 iterations + + var derivedKeyTypes = [ + {algorithm: {name: "AES-CBC", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CBC", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CBC", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-CTR", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 128}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 192}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-GCM", length: 256}, usages: ["encrypt", "decrypt"]}, + {algorithm: {name: "AES-KW", length: 128}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "AES-KW", length: 192}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "AES-KW", length: 256}, usages: ["wrapKey", "unwrapKey"]}, + {algorithm: {name: "HMAC", hash: "SHA-1", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-256", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-384", length: 256}, usages: ["sign", "verify"]}, + {algorithm: {name: "HMAC", hash: "SHA-512", length: 256}, usages: ["sign", "verify"]} + ]; + + var passwords = { + "short": new Uint8Array([80, 64, 115, 115, 119, 48, 114, 100]), + "long": new Uint8Array([85, 115, 101, 114, 115, 32, 115, 104, 111, 117, 108, 100, 32, 112, 105, 99, 107, 32, 108, 111, 110, 103, 32, 112, 97, 115, 115, 112, 104, 114, 97, 115, 101, 115, 32, 40, 110, 111, 116, 32, 117, 115, 101, 32, 115, 104, 111, 114, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100, 115, 41, 33]), + "empty": new Uint8Array([]) + }; + + var salts = { + "short": new Uint8Array([78, 97, 67, 108]), + "long": new Uint8Array([83, 111, 100, 105, 117, 109, 32, 67, 104, 108, 111, 114, 105, 100, 101, 32, 99, 111, 109, 112, 111, 117, 110, 100]), + "empty": new Uint8Array([]) + }; + + var derivations = { + "short": { + "short": { + "SHA-384": { + "1000": new Uint8Array([170, 236, 90, 151, 109, 77, 53, 203, 32, 36, 72, 111, 201, 249, 187, 154, 163, 234, 231, 206, 242, 188, 230, 38, 100, 181, 179, 117, 28, 245, 15, 241]), + "1": new Uint8Array([128, 205, 15, 21, 54, 67, 102, 167, 37, 81, 195, 121, 117, 247, 182, 55, 186, 137, 194, 155, 70, 57, 236, 114, 15, 105, 167, 13, 187, 237, 81, 92]), + "100000": new Uint8Array([111, 94, 163, 198, 198, 245, 228, 131, 52, 103, 180, 124, 58, 103, 30, 101, 113, 78, 135, 7, 27, 209, 227, 109, 113, 111, 132, 107, 92, 210, 137, 128]) + }, + "SHA-512": { + "1000": new Uint8Array([134, 92, 89, 69, 225, 31, 91, 243, 221, 240, 2, 231, 203, 23, 72, 246, 34, 77, 38, 113, 232, 6, 218, 212, 170, 240, 144, 160, 67, 103, 218, 41]), + "1": new Uint8Array([105, 244, 213, 206, 245, 199, 216, 186, 147, 142, 136, 3, 136, 200, 246, 59, 107, 36, 72, 178, 98, 109, 19, 67, 252, 92, 182, 139, 189, 127, 39, 178]), + "100000": new Uint8Array([72, 59, 167, 242, 226, 254, 56, 44, 246, 29, 32, 178, 152, 18, 226, 212, 150, 16, 166, 0, 65, 174, 64, 236, 249, 252, 126, 241, 56, 233, 56, 118]) + }, + "SHA-1": { + "1000": new Uint8Array([83, 136, 234, 94, 98, 225, 181, 87, 152, 26, 190, 92, 228, 19, 33, 39, 88, 170, 106, 157, 44, 91, 240, 140, 1, 157, 69, 157, 186, 102, 107, 144]), + "1": new Uint8Array([70, 36, 219, 210, 19, 115, 238, 86, 89, 193, 37, 177, 132, 238, 218, 162, 106, 51, 183, 124, 161, 19, 20, 185, 240, 201, 218, 225, 228, 78, 155, 4]), + "100000": new Uint8Array([245, 143, 67, 95, 188, 92, 5, 134, 92, 145, 79, 217, 114, 16, 138, 9, 69, 125, 95, 154, 72, 241, 78, 117, 228, 204, 2, 217, 137, 131, 3, 138]) + }, + "SHA-256": { + "1000": new Uint8Array([78, 108, 165, 121, 87, 67, 155, 227, 167, 83, 112, 66, 66, 37, 226, 33, 29, 85, 240, 90, 240, 5, 97, 223, 63, 62, 254, 233, 17, 107, 195, 76]), + "1": new Uint8Array([198, 188, 85, 164, 4, 173, 206, 163, 106, 26, 181, 103, 152, 8, 94, 10, 175, 105, 127, 107, 178, 193, 106, 80, 114, 248, 56, 241, 125, 254, 108, 182]), + "100000": new Uint8Array([171, 37, 121, 101, 152, 231, 75, 41, 195, 36, 245, 186, 77, 144, 234, 125, 200, 159, 198, 137, 16, 65, 180, 213, 108, 148, 21, 101, 5, 247, 34, 192]) + } + }, + "long": { + "SHA-384": { + "1000": new Uint8Array([163, 16, 239, 60, 107, 58, 149, 230, 216, 202, 102, 68, 227, 220, 253, 136, 34, 42, 89, 254, 142, 0, 197, 45, 106, 18, 99, 29, 130, 193, 210, 75]), + "1": new Uint8Array([104, 7, 52, 108, 197, 62, 222, 209, 203, 150, 74, 114, 98, 133, 137, 166, 189, 72, 53, 89, 144, 191, 223, 231, 70, 81, 9, 113, 2, 7, 5, 157]), + "100000": new Uint8Array([44, 140, 102, 116, 200, 121, 207, 24, 80, 188, 155, 127, 189, 204, 110, 167, 171, 176, 161, 82, 33, 150, 168, 102, 135, 83, 5, 222, 165, 116, 134, 243]) + }, + "SHA-512": { + "1000": new Uint8Array([156, 23, 254, 150, 137, 94, 173, 191, 209, 204, 9, 95, 193, 187, 131, 79, 40, 229, 204, 201, 236, 150, 202, 129, 76, 255, 148, 26, 75, 244, 7, 39]), + "1": new Uint8Array([87, 119, 2, 122, 255, 64, 81, 251, 155, 67, 193, 241, 239, 4, 99, 189, 103, 117, 17, 117, 212, 40, 161, 61, 163, 218, 132, 90, 89, 19, 50, 205]), + "100000": new Uint8Array([180, 121, 201, 113, 92, 66, 22, 56, 220, 224, 167, 5, 252, 11, 123, 167, 213, 111, 163, 6, 49, 136, 6, 53, 128, 224, 112, 223, 241, 219, 73, 124]) + }, + "SHA-1": { + "1000": new Uint8Array([137, 211, 178, 123, 95, 110, 138, 240, 21, 242, 248, 124, 243, 104, 161, 67, 138, 32, 108, 78, 207, 95, 230, 129, 252, 59, 249, 76, 86, 33, 62, 246]), + "1": new Uint8Array([87, 111, 124, 22, 88, 37, 190, 249, 239, 20, 180, 188, 44, 130, 70, 157, 30, 64, 143, 248, 231, 186, 48, 102, 148, 121, 127, 158, 69, 183, 102, 237]), + "100000": new Uint8Array([30, 57, 232, 191, 102, 118, 252, 211, 21, 102, 85, 69, 122, 250, 20, 190, 231, 113, 219, 203, 252, 208, 114, 65, 199, 206, 226, 9, 167, 203, 31, 233]) + }, + "SHA-256": { + "1000": new Uint8Array([177, 167, 183, 220, 32, 223, 23, 74, 74, 14, 65, 13, 191, 175, 3, 180, 195, 117, 196, 80, 168, 157, 122, 158, 211, 73, 180, 229, 46, 100, 223, 216]), + "1": new Uint8Array([18, 185, 15, 89, 79, 9, 8, 207, 145, 45, 101, 92, 148, 143, 156, 42, 30, 171, 133, 87, 101, 188, 18, 120, 94, 241, 138, 160, 43, 142, 126, 220]), + "100000": new Uint8Array([212, 89, 77, 138, 27, 89, 82, 10, 72, 135, 137, 34, 166, 93, 102, 61, 40, 246, 165, 250, 73, 233, 49, 211, 0, 216, 249, 186, 249, 61, 10, 235]) + } + }, + "empty": { + "SHA-384": { + "1000": new Uint8Array([174, 181, 249, 125, 102, 39, 238, 188, 222, 107, 19, 154, 0, 137, 85, 0, 48, 247, 64, 28, 103, 224, 28, 5, 122, 51, 56, 23, 94, 63, 58, 23]), + "1": new Uint8Array([79, 16, 137, 192, 30, 67, 139, 222, 100, 154, 55, 159, 164, 24, 251, 195, 184, 86, 37, 135, 114, 223, 233, 17, 128, 111, 155, 208, 128, 159, 188, 126]), + "100000": new Uint8Array([215, 104, 125, 246, 199, 129, 220, 136, 214, 78, 249, 203, 175, 149, 211, 213, 209, 21, 95, 102, 178, 48, 35, 158, 110, 129, 193, 85, 12, 136, 64, 207]) + }, + "SHA-512": { + "1000": new Uint8Array([181, 172, 114, 11, 122, 190, 8, 50, 252, 81, 163, 27, 30, 197, 103, 59, 235, 30, 65, 132, 10, 223, 211, 214, 6, 232, 99, 143, 64, 6, 235, 72]), + "1": new Uint8Array([143, 123, 125, 69, 156, 117, 47, 100, 191, 18, 190, 98, 91, 101, 212, 150, 172, 36, 234, 54, 81, 107, 22, 142, 22, 251, 2, 104, 69, 180, 232, 46]), + "100000": new Uint8Array([186, 26, 15, 54, 186, 215, 113, 82, 101, 100, 5, 30, 185, 202, 32, 125, 161, 155, 98, 229, 55, 98, 52, 153, 118, 169, 163, 209, 176, 239, 126, 32]) + }, + "SHA-1": { + "1000": new Uint8Array([115, 111, 60, 61, 110, 188, 194, 167, 185, 112, 64, 62, 38, 150, 192, 235, 76, 209, 119, 15, 85, 241, 150, 252, 112, 137, 230, 102, 193, 31, 119, 218]), + "1": new Uint8Array([192, 207, 251, 12, 229, 219, 53, 31, 170, 36, 218, 213, 144, 37, 131, 207, 195, 10, 159, 84, 217, 170, 105, 145, 254, 130, 29, 3, 18, 33, 39, 233]), + "100000": new Uint8Array([28, 80, 149, 172, 154, 123, 212, 16, 239, 15, 114, 201, 147, 236, 169, 27, 176, 229, 113, 233, 178, 251, 171, 112, 79, 140, 19, 17, 145, 250, 209, 108]) + }, + "SHA-256": { + "1000": new Uint8Array([185, 210, 242, 33, 123, 78, 229, 168, 191, 3, 69, 243, 107, 44, 152, 135, 51, 245, 3, 169, 117, 223, 234, 199, 183, 19, 95, 84, 165, 242, 153, 113]), + "1": new Uint8Array([1, 158, 84, 171, 66, 240, 4, 133, 211, 170, 27, 38, 252, 222, 33, 174, 95, 82, 203, 15, 9, 96, 255, 201, 118, 127, 37, 198, 94, 45, 178, 249]), + "100000": new Uint8Array([167, 162, 134, 152, 41, 121, 120, 7, 179, 229, 118, 193, 120, 120, 180, 102, 68, 158, 137, 230, 4, 71, 213, 65, 119, 90, 150, 235, 124, 26, 93, 237]) + } + } + }, + "long": { + "short": { + "SHA-384": { + "1000": new Uint8Array([250, 164, 66, 251, 171, 244, 5, 140, 198, 83, 104, 181, 61, 126, 197, 17, 60, 9, 234, 126, 94, 55, 67, 49, 47, 75, 235, 237, 217, 128, 186, 55]), + "1": new Uint8Array([94, 222, 136, 54, 253, 171, 238, 197, 211, 115, 59, 67, 74, 186, 196, 67, 212, 21, 25, 59, 89, 158, 9, 38, 25, 59, 0, 15, 64, 106, 90, 125]), + "100000": new Uint8Array([246, 42, 230, 199, 135, 27, 24, 26, 167, 18, 50, 245, 235, 136, 55, 36, 152, 239, 50, 172, 10, 125, 113, 81, 25, 232, 240, 82, 235, 16, 45, 41]) + }, + "SHA-512": { + "1000": new Uint8Array([240, 146, 143, 80, 161, 85, 242, 106, 140, 156, 27, 199, 243, 181, 203, 83, 28, 83, 168, 245, 16, 64, 201, 206, 95, 199, 157, 67, 15, 240, 192, 244]), + "1": new Uint8Array([62, 156, 18, 179, 246, 223, 182, 68, 21, 148, 236, 112, 99, 252, 169, 98, 255, 218, 16, 182, 207, 48, 184, 152, 163, 30, 249, 241, 48, 107, 17, 25]), + "100000": new Uint8Array([151, 74, 207, 187, 15, 15, 32, 200, 30, 201, 40, 41, 243, 140, 61, 175, 8, 106, 125, 245, 139, 145, 43, 133, 109, 31, 94, 204, 147, 85, 239, 27]) + }, + "SHA-1": { + "1000": new Uint8Array([83, 180, 33, 97, 19, 78, 21, 200, 113, 171, 215, 26, 186, 19, 144, 208, 31, 76, 106, 148, 12, 170, 245, 193, 121, 37, 141, 143, 27, 29, 104, 11]), + "1": new Uint8Array([138, 231, 47, 148, 230, 252, 213, 79, 203, 252, 166, 98, 0, 162, 17, 165, 27, 47, 132, 103, 135, 210, 11, 104, 8, 190, 223, 21, 108, 228, 108, 160]), + "100000": new Uint8Array([167, 253, 164, 199, 157, 211, 186, 26, 135, 95, 101, 233, 36, 139, 33, 8, 153, 202, 8, 20, 174, 56, 153, 93, 140, 229, 165, 53, 96, 203, 172, 49]) + }, + "SHA-256": { + "1000": new Uint8Array([238, 235, 119, 20, 66, 10, 0, 177, 138, 206, 194, 181, 151, 157, 29, 166, 19, 115, 32, 43, 127, 139, 167, 27, 8, 98, 147, 170, 184, 89, 224, 160]), + "1": new Uint8Array([255, 161, 233, 167, 39, 169, 44, 39, 174, 111, 116, 177, 199, 151, 143, 158, 26, 248, 96, 225, 6, 55, 99, 64, 172, 67, 217, 105, 209, 54, 64, 91]), + "100000": new Uint8Array([222, 172, 112, 203, 227, 241, 114, 14, 53, 59, 78, 128, 22, 221, 181, 148, 117, 239, 183, 11, 106, 35, 133, 231, 53, 210, 214, 234, 109, 98, 74, 77]) + } + }, + "long": { + "SHA-384": { + "1000": new Uint8Array([53, 101, 133, 81, 240, 236, 19, 57, 138, 123, 69, 224, 38, 28, 253, 101, 76, 30, 82, 65, 30, 110, 69, 125, 238, 104, 244, 174, 171, 233, 37, 167]), + "1": new Uint8Array([207, 85, 66, 44, 239, 110, 27, 196, 158, 109, 8, 43, 34, 115, 212, 128, 232, 242, 232, 130, 45, 173, 209, 70, 156, 42, 50, 217, 101, 125, 18, 241]), + "100000": new Uint8Array([26, 186, 181, 241, 228, 97, 223, 55, 139, 136, 192, 162, 43, 231, 110, 242, 241, 98, 125, 247, 74, 199, 203, 251, 132, 189, 204, 179, 84, 188, 136, 137]) + }, + "SHA-512": { + "1000": new Uint8Array([67, 225, 32, 36, 196, 211, 84, 114, 127, 126, 88, 132, 44, 203, 96, 51, 161, 97, 214, 13, 197, 174, 81, 111, 7, 110, 74, 88, 161, 136, 13, 56]), + "1": new Uint8Array([222, 74, 251, 192, 173, 211, 228, 211, 47, 75, 198, 225, 34, 168, 138, 228, 74, 43, 60, 207, 1, 72, 231, 118, 43, 172, 5, 196, 62, 148, 239, 127]), + "100000": new Uint8Array([249, 169, 35, 132, 164, 234, 223, 195, 86, 6, 73, 179, 127, 182, 118, 232, 60, 69, 60, 187, 217, 159, 128, 187, 166, 240, 161, 14, 189, 21, 11, 82]) + }, + "SHA-1": { + "1000": new Uint8Array([110, 144, 200, 110, 224, 123, 135, 62, 150, 80, 113, 2, 86, 115, 255, 5, 66, 159, 103, 140, 48, 249, 27, 55, 225, 226, 218, 81, 32, 54, 211, 32]), + "1": new Uint8Array([29, 16, 78, 165, 210, 53, 0, 106, 18, 168, 15, 113, 184, 14, 229, 40, 4, 139, 100, 204, 26, 122, 15, 48, 247, 223, 75, 162, 107, 131, 32, 199]), + "100000": new Uint8Array([20, 16, 48, 118, 59, 249, 131, 200, 86, 77, 93, 76, 147, 95, 227, 202, 53, 73, 96, 129, 89, 172, 25, 52, 193, 89, 144, 64, 102, 140, 35, 99]) + }, + "SHA-256": { + "1000": new Uint8Array([63, 213, 135, 201, 75, 169, 70, 184, 185, 220, 205, 221, 42, 91, 116, 246, 119, 141, 79, 97, 230, 145, 248, 58, 196, 122, 47, 169, 88, 11, 253, 248]), + "1": new Uint8Array([253, 92, 174, 184, 179, 171, 229, 137, 188, 21, 156, 78, 81, 248, 0, 87, 14, 116, 246, 67, 151, 166, 197, 238, 19, 29, 254, 217, 63, 5, 17, 170]), + "100000": new Uint8Array([17, 153, 45, 139, 129, 51, 17, 36, 76, 84, 75, 98, 41, 41, 69, 226, 8, 212, 3, 206, 189, 107, 149, 82, 161, 165, 98, 6, 93, 153, 88, 234]) + } + }, + "empty": { + "SHA-384": { + "1000": new Uint8Array([249, 202, 20, 139, 12, 4, 24, 144, 191, 248, 131, 29, 182, 23, 71, 25, 126, 148, 206, 104, 241, 144, 237, 242, 105, 105, 75, 77, 100, 72, 97, 202]), + "1": new Uint8Array([73, 171, 63, 159, 136, 47, 219, 158, 82, 139, 77, 159, 27, 62, 140, 113, 210, 99, 154, 191, 23, 1, 213, 110, 185, 155, 213, 18, 1, 228, 32, 255]), + "100000": new Uint8Array([23, 73, 223, 205, 119, 229, 37, 133, 25, 234, 34, 49, 186, 44, 214, 84, 59, 7, 51, 57, 172, 155, 21, 69, 187, 100, 49, 83, 250, 246, 209, 123]) + }, + "SHA-512": { + "1000": new Uint8Array([69, 122, 121, 85, 235, 236, 236, 113, 165, 30, 251, 98, 55, 229, 177, 214, 47, 77, 234, 181, 201, 61, 123, 61, 17, 209, 231, 15, 175, 250, 65, 126]), + "1": new Uint8Array([209, 191, 161, 166, 184, 169, 119, 131, 159, 140, 63, 157, 82, 221, 2, 16, 78, 32, 41, 192, 235, 42, 98, 8, 204, 64, 136, 22, 231, 118, 138, 140]), + "100000": new Uint8Array([232, 5, 172, 156, 193, 216, 65, 44, 66, 68, 109, 35, 125, 27, 80, 79, 149, 64, 179, 98, 189, 27, 117, 228, 81, 83, 30, 133, 62, 36, 117, 61]) + }, + "SHA-1": { + "1000": new Uint8Array([231, 55, 93, 229, 3, 103, 102, 196, 12, 184, 95, 67, 181, 63, 206, 79, 250, 64, 42, 182, 190, 53, 113, 0, 126, 245, 213, 84, 83, 253, 127, 10]), + "1": new Uint8Array([164, 106, 98, 152, 109, 156, 57, 9, 244, 16, 20, 221, 114, 207, 227, 74, 38, 18, 71, 133, 77, 115, 18, 207, 79, 190, 173, 96, 185, 182, 158, 221]), + "100000": new Uint8Array([122, 64, 61, 154, 19, 174, 216, 22, 78, 156, 7, 44, 84, 84, 98, 37, 31, 217, 66, 241, 115, 106, 107, 240, 60, 225, 200, 131, 48, 4, 142, 4]) + }, + "SHA-256": { + "1000": new Uint8Array([126, 102, 200, 75, 234, 136, 143, 146, 195, 72, 217, 20, 85, 133, 24, 108, 174, 71, 43, 18, 251, 167, 240, 173, 40, 23, 149, 117, 193, 170, 129, 90]), + "1": new Uint8Array([79, 81, 12, 81, 129, 172, 92, 44, 95, 212, 189, 20, 31, 151, 18, 73, 91, 236, 162, 121, 98, 71, 66, 180, 214, 211, 13, 8, 185, 108, 10, 105]), + "100000": new Uint8Array([95, 26, 106, 196, 165, 109, 151, 150, 167, 48, 154, 120, 218, 170, 249, 24, 186, 218, 245, 237, 30, 236, 195, 240, 184, 163, 164, 76, 61, 56, 214, 84]) + } + } + }, + "empty": { + "short": { + "SHA-384": { + "1000": new Uint8Array([127, 247, 149, 74, 237, 223, 65, 121, 95, 200, 48, 6, 102, 120, 109, 73, 116, 38, 154, 169, 28, 199, 233, 56, 17, 201, 83, 51, 29, 86, 214, 9]), + "1": new Uint8Array([233, 240, 218, 30, 151, 223, 164, 85, 248, 88, 206, 107, 154, 241, 236, 192, 41, 159, 18, 95, 241, 168, 71, 235, 93, 73, 85, 134, 111, 67, 230, 4]), + "100000": new Uint8Array([28, 115, 19, 43, 106, 85, 233, 217, 222, 44, 219, 254, 31, 85, 191, 10, 181, 159, 217, 31, 120, 241, 9, 197, 0, 150, 3, 139, 133, 87, 177, 71]) + }, + "SHA-512": { + "1000": new Uint8Array([213, 97, 196, 200, 78, 156, 96, 186, 71, 82, 162, 211, 131, 191, 85, 239, 246, 67, 252, 158, 69, 34, 82, 214, 130, 30, 57, 68, 147, 80, 207, 114]), + "1": new Uint8Array([231, 226, 180, 31, 72, 135, 66, 27, 203, 118, 78, 180, 165, 111, 99, 210, 80, 46, 51, 199, 100, 251, 223, 96, 98, 106, 212, 46, 217, 103, 35, 66]), + "100000": new Uint8Array([239, 208, 7, 82, 188, 159, 250, 251, 90, 57, 157, 209, 213, 131, 78, 141, 44, 43, 103, 110, 205, 75, 32, 99, 251, 31, 229, 129, 208, 241, 56, 11]) + }, + "SHA-1": { + "1000": new Uint8Array([114, 201, 43, 189, 61, 218, 180, 120, 158, 136, 228, 42, 209, 205, 168, 60, 192, 114, 158, 108, 181, 16, 106, 87, 126, 80, 213, 207, 97, 120, 36, 129]), + "1": new Uint8Array([166, 103, 218, 71, 184, 248, 87, 183, 198, 95, 112, 166, 200, 231, 160, 108, 224, 210, 82, 17, 162, 182, 235, 175, 88, 220, 170, 242, 104, 180, 107, 29]), + "100000": new Uint8Array([6, 225, 158, 27, 131, 230, 72, 11, 21, 84, 223, 43, 49, 162, 201, 45, 27, 252, 249, 188, 27, 219, 200, 117, 31, 248, 104, 91, 222, 239, 125, 201]) + }, + "SHA-256": { + "1000": new Uint8Array([40, 53, 243, 237, 83, 86, 84, 32, 201, 9, 81, 80, 155, 12, 17, 115, 182, 69, 23, 79, 21, 70, 171, 58, 195, 230, 200, 92, 180, 113, 181, 59]), + "1": new Uint8Array([45, 219, 73, 36, 62, 179, 181, 145, 44, 178, 96, 205, 216, 127, 176, 78, 240, 209, 17, 191, 164, 77, 64, 164, 94, 2, 168, 165, 195, 193, 81, 141]), + "100000": new Uint8Array([128, 174, 217, 5, 202, 50, 174, 11, 178, 169, 216, 245, 50, 240, 72, 160, 230, 114, 70, 62, 239, 159, 131, 223, 167, 216, 139, 202, 114, 101, 83, 234]) + } + }, + "long": { + "SHA-384": { + "1000": new Uint8Array([139, 184, 156, 247, 25, 114, 254, 90, 204, 22, 253, 197, 248, 207, 253, 44, 46, 113, 120, 192, 134, 179, 187, 230, 28, 193, 49, 70, 25, 19, 89, 88]), + "1": new Uint8Array([123, 11, 204, 168, 29, 214, 55, 163, 179, 57, 134, 102, 97, 151, 22, 197, 242, 177, 244, 165, 194, 78, 133, 193, 138, 153, 85, 85, 158, 77, 118, 146]), + "100000": new Uint8Array([38, 198, 168, 174, 75, 209, 251, 231, 21, 174, 71, 142, 255, 243, 236, 174, 131, 175, 166, 23, 237, 53, 189, 74, 63, 99, 195, 218, 118, 164, 45, 34]) + }, + "SHA-512": { + "1000": new Uint8Array([92, 172, 193, 108, 223, 190, 5, 44, 253, 115, 169, 137, 27, 140, 14, 120, 177, 155, 46, 7, 234, 226, 66, 61, 72, 254, 213, 224, 138, 168, 73, 75]), + "1": new Uint8Array([187, 115, 248, 22, 138, 143, 57, 29, 61, 84, 202, 137, 47, 183, 43, 142, 96, 53, 227, 127, 137, 30, 90, 112, 73, 27, 148, 220, 5, 81, 11, 196]), + "100000": new Uint8Array([135, 253, 252, 41, 51, 146, 203, 243, 62, 204, 155, 81, 65, 162, 254, 250, 116, 209, 80, 73, 151, 86, 134, 60, 72, 76, 10, 120, 182, 39, 77, 127]) + }, + "SHA-1": { + "1000": new Uint8Array([204, 87, 72, 236, 196, 18, 136, 160, 225, 51, 104, 84, 58, 170, 46, 246, 44, 151, 186, 117, 24, 250, 136, 246, 225, 28, 53, 118, 63, 201, 48, 180]), + "1": new Uint8Array([31, 70, 180, 12, 242, 251, 61, 196, 26, 61, 156, 237, 136, 151, 184, 97, 5, 3, 104, 16, 226, 191, 172, 112, 64, 129, 75, 214, 93, 66, 141, 103]), + "100000": new Uint8Array([51, 226, 153, 59, 244, 114, 157, 201, 147, 255, 246, 110, 105, 204, 85, 119, 113, 53, 235, 250, 188, 229, 51, 87, 91, 206, 74, 150, 100, 90, 116, 44]) + }, + "SHA-256": { + "1000": new Uint8Array([19, 83, 247, 69, 130, 55, 171, 51, 46, 224, 82, 226, 159, 130, 154, 42, 185, 14, 114, 99, 14, 161, 4, 147, 180, 238, 207, 251, 159, 248, 158, 29]), + "1": new Uint8Array([97, 201, 53, 196, 98, 195, 50, 28, 137, 102, 53, 69, 209, 58, 79, 107, 82, 181, 25, 28, 251, 116, 121, 229, 141, 207, 230, 68, 77, 67, 16, 108]), + "100000": new Uint8Array([121, 186, 248, 14, 197, 130, 146, 5, 56, 128, 30, 157, 146, 156, 224, 112, 132, 39, 121, 135, 72, 141, 115, 58, 2, 104, 82, 196, 82, 240, 111, 180]) + } + }, + "empty": { + "SHA-384": { + "1000": new Uint8Array([156, 191, 231, 45, 25, 77, 163, 78, 23, 200, 33, 221, 21, 105, 239, 80, 168, 110, 180, 216, 147, 89, 23, 118, 173, 198, 165, 194, 30, 0, 49, 207]), + "1": new Uint8Array([75, 176, 66, 165, 194, 140, 238, 111, 102, 249, 145, 199, 23, 253, 119, 2, 103, 120, 126, 43, 179, 3, 30, 174, 39, 13, 135, 214, 58, 217, 149, 52]), + "100000": new Uint8Array([237, 107, 215, 40, 37, 103, 171, 228, 141, 84, 45, 6, 125, 9, 244, 4, 189, 4, 74, 226, 206, 254, 17, 218, 204, 83, 28, 71, 100, 205, 53, 205]) + }, + "SHA-512": { + "1000": new Uint8Array([203, 147, 9, 108, 58, 2, 190, 235, 28, 95, 172, 54, 118, 92, 144, 17, 254, 153, 248, 216, 234, 98, 54, 96, 72, 252, 152, 203, 152, 223, 234, 143]), + "1": new Uint8Array([109, 46, 203, 187, 251, 46, 109, 205, 112, 86, 250, 249, 175, 106, 160, 110, 174, 89, 67, 145, 219, 152, 50, 121, 166, 191, 39, 224, 235, 34, 134, 20]), + "100000": new Uint8Array([137, 225, 98, 84, 235, 173, 92, 186, 114, 224, 174, 190, 22, 20, 199, 249, 183, 149, 167, 80, 95, 38, 55, 32, 108, 225, 10, 52, 73, 162, 184, 187]) + }, + "SHA-1": { + "1000": new Uint8Array([110, 64, 145, 10, 192, 46, 200, 156, 235, 185, 216, 152, 177, 58, 9, 209, 205, 122, 223, 111, 140, 192, 140, 196, 115, 48, 44, 137, 115, 170, 46, 25]), + "1": new Uint8Array([30, 67, 122, 28, 121, 215, 91, 230, 30, 145, 20, 29, 174, 32, 175, 252, 72, 146, 204, 153, 171, 204, 63, 231, 83, 136, 123, 204, 200, 146, 1, 118]), + "100000": new Uint8Array([169, 225, 190, 187, 54, 188, 38, 215, 201, 151, 213, 72, 60, 188, 141, 228, 164, 25, 209, 231, 6, 87, 19, 66, 99, 37, 134, 236, 51, 10, 114, 144]) + }, + "SHA-256": { + "1000": new Uint8Array([79, 197, 138, 33, 193, 0, 206, 24, 53, 184, 249, 153, 29, 115, 139, 86, 150, 93, 20, 178, 78, 23, 97, 251, 223, 252, 105, 172, 94, 11, 102, 122]), + "1": new Uint8Array([247, 206, 11, 101, 61, 45, 114, 164, 16, 140, 245, 171, 233, 18, 255, 221, 119, 118, 22, 219, 187, 39, 167, 14, 130, 4, 243, 174, 45, 15, 111, 173]), + "100000": new Uint8Array([100, 168, 104, 212, 178, 58, 246, 150, 211, 115, 77, 11, 129, 77, 4, 205, 209, 172, 40, 1, 40, 233, 118, 83, 160, 95, 50, 180, 156, 19, 162, 154]) + } + } + } + }; + + return {passwords: passwords, salts: salts, derivations: derivations, derivedKeyTypes: derivedKeyTypes}; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js new file mode 100644 index 00000000000000..379d9311f30247 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/digest/digest.https.any.js @@ -0,0 +1,152 @@ +// META: title=WebCryptoAPI: digest() +// META: timeout=long + + var subtle = crypto.subtle; // Change to test prefixed implementations + + var sourceData = { + empty: new Uint8Array(0), + short: new Uint8Array([21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255]), + medium: new Uint8Array([182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, 171, 172, 161, 147]) + }; + + sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength); + for (var i=0; i<1024; i++) { + sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength); + } + + var digestedData = { + "sha-1": { + empty: new Uint8Array([218, 57, 163, 238, 94, 107, 75, 13, 50, 85, 191, 239, 149, 96, 24, 144, 175, 216, 7, 9]), + short: new Uint8Array([201, 19, 24, 205, 242, 57, 106, 1, 94, 63, 78, 106, 134, 160, 186, 101, 184, 99, 89, 68]), + medium: new Uint8Array([229, 65, 6, 8, 112, 235, 22, 191, 51, 182, 142, 81, 245, 19, 82, 104, 147, 152, 103, 41]), + long: new Uint8Array([48, 152, 181, 0, 55, 236, 208, 46, 189, 101, 118, 83, 178, 191, 160, 30, 238, 39, 162, 234]) + }, + "sha-256": { + empty: new Uint8Array([227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]), + short: new Uint8Array([162, 131, 17, 134, 152, 71, 146, 199, 211, 45, 89, 200, 151, 64, 104, 127, 25, 173, 220, 27, 149, 158, 113, 161, 204, 83, 138, 59, 126, 216, 67, 242]), + medium: new Uint8Array([83, 83, 103, 135, 126, 240, 20, 215, 252, 113, 126, 92, 183, 132, 62, 89, 182, 26, 238, 98, 199, 2, 156, 236, 126, 198, 193, 47, 217, 36, 224, 228]), + long: new Uint8Array([20, 205, 234, 157, 199, 95, 90, 98, 116, 217, 252, 30, 100, 0, 153, 18, 241, 220, 211, 6, 180, 143, 232, 233, 207, 18, 45, 230, 113, 87, 23, 129]) + }, + "sha-384": { + empty: new Uint8Array([56, 176, 96, 167, 81, 172, 150, 56, 76, 217, 50, 126, 177, 177, 227, 106, 33, 253, 183, 17, 20, 190, 7, 67, 76, 12, 199, 191, 99, 246, 225, 218, 39, 78, 222, 191, 231, 111, 101, 251, 213, 26, 210, 241, 72, 152, 185, 91]), + short: new Uint8Array([107, 245, 234, 101, 36, 209, 205, 220, 67, 247, 207, 59, 86, 238, 5, 146, 39, 64, 74, 47, 83, 143, 2, 42, 61, 183, 68, 122, 120, 44, 6, 193, 237, 5, 232, 171, 79, 94, 220, 23, 243, 113, 20, 64, 223, 233, 119, 49]), + medium: new Uint8Array([203, 194, 197, 136, 254, 91, 37, 249, 22, 218, 40, 180, 228, 122, 72, 74, 230, 252, 31, 228, 144, 45, 213, 201, 147, 154, 107, 253, 3, 74, 179, 180, 139, 57, 8, 116, 54, 1, 31, 106, 153, 135, 157, 39, 149, 64, 233, 119]), + long: new Uint8Array([73, 244, 253, 179, 152, 25, 104, 249, 125, 87, 55, 15, 133, 52, 80, 103, 205, 82, 150, 169, 125, 209, 161, 142, 6, 145, 30, 117, 110, 150, 8, 73, 37, 41, 135, 14, 26, 209, 48, 153, 141, 87, 203, 251, 183, 193, 208, 158]) + }, + "sha-512": { + empty: new Uint8Array([207, 131, 225, 53, 126, 239, 184, 189, 241, 84, 40, 80, 214, 109, 128, 7, 214, 32, 228, 5, 11, 87, 21, 220, 131, 244, 169, 33, 211, 108, 233, 206, 71, 208, 209, 60, 93, 133, 242, 176, 255, 131, 24, 210, 135, 126, 236, 47, 99, 185, 49, 189, 71, 65, 122, 129, 165, 56, 50, 122, 249, 39, 218, 62]), + short: new Uint8Array([55, 82, 72, 190, 95, 243, 75, 231, 76, 171, 79, 241, 195, 188, 141, 198, 139, 213, 248, 223, 244, 2, 62, 152, 248, 123, 134, 92, 255, 44, 114, 66, 146, 223, 24, 148, 67, 166, 79, 244, 19, 74, 101, 205, 70, 53, 185, 212, 245, 220, 13, 63, 182, 117, 40, 0, 42, 99, 172, 242, 108, 157, 165, 117]), + medium: new Uint8Array([185, 16, 159, 131, 158, 142, 164, 60, 137, 15, 41, 60, 225, 29, 198, 226, 121, 141, 30, 36, 49, 241, 228, 185, 25, 227, 178, 12, 79, 54, 48, 59, 163, 156, 145, 109, 179, 6, 196, 90, 59, 101, 118, 31, 245, 190, 133, 50, 142, 234, 244, 44, 56, 48, 241, 217, 94, 122, 65, 22, 91, 125, 45, 54]), + long: new Uint8Array([75, 2, 202, 246, 80, 39, 96, 48, 234, 86, 23, 229, 151, 197, 213, 63, 217, 218, 166, 139, 120, 191, 230, 11, 34, 170, 184, 211, 106, 76, 42, 58, 255, 219, 113, 35, 79, 73, 39, 103, 55, 197, 117, 221, 247, 77, 20, 5, 76, 189, 111, 219, 152, 253, 13, 220, 188, 180, 111, 145, 173, 118, 182, 238]) + }, + } + + // Try every combination of hash with source data size. Variations tested are + // hash name in upper, lower, or mixed case, and upper-case version with the + // source buffer altered after call. + Object.keys(sourceData).forEach(function(size) { + Object.keys(digestedData).forEach(function(alg) { + var upCase = alg.toUpperCase(); + var downCase = alg.toLowerCase(); + var mixedCase = upCase.substr(0, 1) + downCase.substr(1); + + promise_test(function(test) { + var promise = subtle.digest({name: upCase}, sourceData[size]) + .then(function(result) { + assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); + }, function(err) { + assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); + }); + + return promise; + }, upCase + " with " + size + " source data"); + + promise_test(function(test) { + var promise = subtle.digest({name: downCase}, sourceData[size]) + .then(function(result) { + assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); + }, function(err) { + assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); + }); + + return promise; + }, downCase + " with " + size + " source data"); + + promise_test(function(test) { + var promise = subtle.digest({name: mixedCase}, sourceData[size]) + .then(function(result) { + assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); + }, function(err) { + assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); + }); + + return promise; + }, mixedCase + " with " + size + " source data"); + + promise_test(function(test) { + var copiedBuffer = copyBuffer(sourceData[size]); + var promise = subtle.digest({name: upCase}, copiedBuffer) + .then(function(result) { + assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); + }, function(err) { + assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); + }); + + copiedBuffer[0] = 255 - copiedBuffer; + return promise; + }, upCase + " with " + size + " source data and altered buffer after call"); + + }); + }); + + // Call digest() with bad algorithm names to get an error + var badNames = ["AES-GCM", "RSA-OAEP", "PBKDF2", "AES-KW"]; + Object.keys(sourceData).forEach(function(size) { + badNames.forEach(function(badName) { + + promise_test(function(test) { + var promise = subtle.digest({name: badName}, sourceData[size]) + .then(function(result) { + assert_unreached("digest() should not have worked for " + badName + ":" + size); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "Bad algorithm name should cause NotSupportedError") + }); + + return promise; + }, badName + " with " + size); + + }); + }); + + + done(); + + + // Returns a copy of the sourceBuffer it is sent. + function copyBuffer(sourceBuffer) { + var source = new Uint8Array(sourceBuffer); + var copy = new Uint8Array(sourceBuffer.byteLength) + + for (var i=0; i { + assert_equals(self.crypto.subtle, undefined); + assert_false("subtle" in self.crypto); +}, "Non-secure context window does not have access to crypto.subtle"); + +test(() => { + assert_equals(self.SubtleCrypto, undefined); + assert_false("SubtleCrypto" in self); +}, "Non-secure context window does not have access to SubtleCrypto") + +test(() => { + assert_equals(self.CryptoKey, undefined); + assert_false("CryptoKey" in self); +}, "Non-secure context window does not have access to CryptoKey") diff --git a/test/fixtures/wpt/WebCryptoAPI/idlharness.https.any.js b/test/fixtures/wpt/WebCryptoAPI/idlharness.https.any.js new file mode 100644 index 00000000000000..ae65eb49f2120e --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/idlharness.https.any.js @@ -0,0 +1,16 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: timeout=long + +// https://w3c.github.io/webcrypto/Overview.html + +idl_test( + ['WebCryptoAPI'], + ['html', 'dom'], + idl_array => { + idl_array.add_objects({ + Crypto: ['crypto'], + SubtleCrypto: ['crypto.subtle'] + }); + } +); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js new file mode 100644 index 00000000000000..628d81ef500f24 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ec_importKey.https.any.js @@ -0,0 +1,279 @@ +// META: title=WebCryptoAPI: importKey() for EC keys +// META: timeout=long + +// Test importKey and exportKey for EC algorithms. Only "happy paths" are +// currently tested - those where the operation should succeed. + + var subtle = crypto.subtle; + + var curves = ['P-256', 'P-384', 'P-521']; + + var keyData = { + "P-521": { + spki: new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), + pkcs8: new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 0, 244, 8, 117, 131, 104, 186, 147, 15, 48, 247, 106, 224, 84, 254, 92, 210, 206, 127, 218, 44, 159, 118, 166, 212, 54, 207, 117, 214, 108, 68, 11, 254, 99, 49, 199, 193, 114, 161, 36, 120, 25, 60, 130, 81, 72, 123, 201, 18, 99, 250, 80, 33, 127, 133, 255, 99, 111, 89, 205, 84, 110, 58, 180, 131, 180, 161, 129, 137, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), + jwk: { + kty: "EC", + crv: "P-521", + x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_", + y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", + d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" + } + }, + + "P-256": { + spki: new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), + pkcs8: new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 19, 211, 58, 45, 90, 191, 156, 249, 235, 178, 31, 248, 96, 212, 174, 254, 110, 86, 231, 119, 144, 244, 222, 233, 180, 8, 132, 235, 211, 53, 68, 234, 161, 68, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), + jwk: { + kty: "EC", + crv: "P-256", + x: "0hCwpvnZ8BKGgFi0P6T0cQGFQ7ugDJJQ35JXwqyuXdE", + y: "zgN1UtSBRQzjm00QlXAbF1v6s0uObAmeGPHBmDWDYeg", + d: "E9M6LVq_nPnrsh_4YNSu_m5W53eQ9N7ptAiE69M1ROo" + } + }, + + "P-384": { + spki: new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), + pkcs8: new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 69, 55, 181, 153, 7, 132, 211, 194, 210, 46, 150, 168, 249, 47, 161, 170, 73, 46, 232, 115, 229, 118, 164, 21, 130, 225, 68, 24, 60, 152, 136, 209, 14, 107, 158, 180, 206, 212, 178, 204, 64, 18, 228, 172, 94, 168, 64, 115, 161, 100, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), + jwk: { + kty: "EC", + crv: "P-384", + x: "IZwU1mYXs27G2IVrOFtzp000T9iude8EZDXdpU47RL1fvevR0I3Wni19wdwhjLQ1", + y: "vSgTjMd4M3qEL2vWGyQOdCSfJGZ8KlgQp2v8KOAzX4imUB3sAZdtqFr7AIactqzo", + d: "RTe1mQeE08LSLpao-S-hqkku6HPldqQVguFEGDyYiNEOa560ztSyzEAS5KxeqEBz" + } + }, + + }; + + // combinations to test + var testVectors = [ + {name: "ECDSA", privateUsages: ["sign"], publicUsages: ["verify"]}, + {name: "ECDH", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []} + ]; + + // TESTS ARE HERE: + // Test every test vector, along with all available key data + testVectors.forEach(function(vector) { + curves.forEach(function(curve) { + + [true, false].forEach(function(extractable) { + + // Test public keys first + [[]].forEach(function(usages) { // Only valid usages argument is empty array + ['spki', 'jwk'].forEach(function(format) { + var algorithm = {name: vector.name, namedCurve: curve}; + var data = keyData[curve]; + if (format === "jwk") { // Not all fields used for public keys + data = {jwk: {kty: keyData[curve].jwk.kty, crv: keyData[curve].jwk.crv, x: keyData[curve].jwk.x, y: keyData[curve].jwk.y}}; + } + + testFormat(format, algorithm, data, curve, usages, extractable); + }); + + }); + + // Next, test private keys + allValidUsages(vector.privateUsages, []).forEach(function(usages) { + ['pkcs8', 'jwk'].forEach(function(format) { + var algorithm = {name: vector.name, namedCurve: curve}; + var data = keyData[curve]; + + testFormat(format, algorithm, data, curve, usages, extractable); + }); + }); + }); + + }); + }); + + + // Test importKey with a given key format and other parameters. If + // extrable is true, export the key and verify that it matches the input. + function testFormat(format, algorithm, keyData, keySize, usages, extractable) { + promise_test(function(test) { + return subtle.importKey(format, keyData[format], algorithm, extractable, usages). + then(function(key) { + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); + if (!extractable) { + return; + } + + return subtle.exportKey(format, key). + then(function(result) { + if (format !== "jwk") { + assert_true(equalBuffers(keyData[format], result), "Round trip works"); + } else { + assert_true(equalJwk(keyData[format], result), "Round trip works"); + } + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], algorithm, extractable, usages)); + } + + + + // Helper methods follow: + + // Are two array buffers the same? + function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i=0; i 0) { + allNonemptySubsetsOf(remainingElements).forEach(function(combination) { + combination.push(firstElement); + results.push(combination); + }); + } + } + + return results; + } + + // Return a list of all valid usage combinations, given the possible ones + // and the ones that are required for a particular operation. + function allValidUsages(possibleUsages, requiredUsages) { + var allUsages = []; + + allNonemptySubsetsOf(possibleUsages).forEach(function(usage) { + for (var i=0; i 0) { + allNonemptySubsetsOf(remainingElements).forEach(function(combination) { + combination.push(firstElement); + results.push(combination); + }); + } + } + + return results; + } + + // Return a list of all valid usage combinations, given the possible ones + // and the ones that are required for a particular operation. + function allValidUsages(possibleUsages, requiredUsages) { + var allUsages = []; + + allNonemptySubsetsOf(possibleUsages).forEach(function(usage) { + for (var i=0; i 0) { + allNonemptySubsetsOf(remainingElements).forEach(function(combination) { + combination.push(firstElement); + results.push(combination); + }); + } + } + + return results; + } + + // Return a list of all valid usage combinations, given the possible ones + // and the ones that are required for a particular operation. + function allValidUsages(possibleUsages, requiredUsages) { + var allUsages = []; + + allNonemptySubsetsOf(possibleUsages).forEach(function(usage) { + for (var i=0; i + + + + + + + + + diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.https.any.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.https.any.js new file mode 100644 index 00000000000000..9764cc33540c08 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: sign() and verify() Using ECDSA +// META: script=ecdsa_vectors.js +// META: script=ecdsa.js +// META: timeout=long + +run_test(); diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js new file mode 100644 index 00000000000000..6133a7ecba290c --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/ecdsa.js @@ -0,0 +1,482 @@ + +function run_test() { + setup({explicit_done: true}); + + var subtle = self.crypto.subtle; // Change to test prefixed implementations + + // When are all these tests really done? When all the promises they use have resolved. + var all_promises = []; + + // Source file [algorithm_name]_vectors.js provides the getTestVectors method + // for the algorithm that drives these tests. + var testVectors = getTestVectors(); + + // Test verification first, because signing tests rely on that working + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification"); + }); + + all_promises.push(promise); + }); + + // Test verification with an altered buffer after call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + signature[0] = 255 - signature[0]; + return operation; + }, vector.name + " verification with altered signature after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); + }); + + all_promises.push(promise); + }); + + // Check for successful verification even if plaintext is altered after call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + plaintext[0] = 255 - plaintext[0]; + return operation; + }, vector.name + " with altered plaintext after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); + }); + + all_promises.push(promise); + }); + + // Check for failures due to using privateKey to verify. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + return subtle.verify(algorithm, vector.privateKey, vector.signature, vector.plaintext) + .then(function(plaintext) { + assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name + ": " + err.message + "'"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }); + }, vector.name + " using privateKey to verify"); + + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " using privateKey to verify"); + }); + + all_promises.push(promise); + }); + + // Check for failures due to using publicKey to sign. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + return subtle.sign(algorithm, vector.publicKey, vector.plaintext) + .then(function(signature) { + assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name + ": " + err.message + "'"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }); + }, vector.name + " using publicKey to sign"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " using publicKey to sign"); + }); + + all_promises.push(promise); + }); + + // Check for failures due to no "verify" usage. + testVectors.forEach(function(originalVector) { + var vector = Object.assign({}, originalVector); + + var promise = importVectorKeys(vector, [], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + return subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) + .then(function(plaintext) { + assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": " + err.message + "'"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }); + }, vector.name + " no verify usage"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " no verify usage"); + }); + + all_promises.push(promise); + }); + + // Check for successful signing and verification. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + return subtle.sign(algorithm, vector.privateKey, vector.plaintext) + .then(function(signature) { + // Can we verify the signature? + return subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Round trip verification works"); + return signature; + }, function(err) { + assert_unreached("verify error for test " + vector.name + ": " + err.message + "'"); + }); + }, function(err) { + assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'"); + }); + }, vector.name + " round trip"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested signing or verifying + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " round trip"); + }); + + all_promises.push(promise); + }); + + // Test signing with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) + .then(function(wrongKey) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + return importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var operation = subtle.sign(algorithm, wrongKey, vector.plaintext) + .then(function(signature) { + assert_unreached("Signing should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " signing with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); + }); + }, function(err) { + promise_test(function(test) { + assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Test verification with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) + .then(function(wrongKey) { + return importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + promise_test(function(test) { + var operation = subtle.verify(algorithm, wrongKey, vector.signature, vector.plaintext) + .then(function(signature) { + assert_unreached("Verifying should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verifying with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); + }); + }, function(err) { + promise_test(function(test) { + assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Test verification fails with wrong signature + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to altered signature"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to altered signature"); + }); + + all_promises.push(promise); + }); + + // Test verification fails with wrong hash + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var hashName = "SHA-1"; + if (vector.hashName === "SHA-1") { + hashName = "SHA-256" + } + var algorithm = {name: vector.algorithmName, hash: hashName}; + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to wrong hash"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to wrong hash"); + }); + + all_promises.push(promise); + }); + + // Test verification fails with bad hash name + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + // use the wrong name for the hash + var hashName = vector.hashName.substring(0, 3) + vector.hashName.substring(4); + var algorithm = {name: vector.algorithmName, hash: hashName}; + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_unreached("Verification should throw an error"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "Correctly throws NotSupportedError for illegal hash name") + }); + + return operation; + }, vector.name + " verification failure due to bad hash name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to bad hash name"); + }); + + all_promises.push(promise); + }); + + // Test verification fails with short (odd length) signature + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + var signature = vector.signature.slice(1); // Skip the first byte + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to shortened signature"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to shortened signature"); + }); + + all_promises.push(promise); + }); + + // Test verification fails with wrong plaintext + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + var algorithm = {name: vector.algorithmName, hash: vector.hashName}; + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + promise_test(function(test) { + var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to altered plaintext"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to altered plaintext"); + }); + + all_promises.push(promise); + }); + + + promise_test(function() { + return Promise.all(all_promises) + .then(function() {done();}) + .catch(function() {done();}) + }, "setup"); + + // A test vector has all needed fields for signing and verifying, EXCEPT that the + // key field may be null. This function replaces that null with the Correct + // CryptoKey object. + // + // Returns a Promise that yields an updated vector on success. + function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { + var publicPromise, privatePromise; + + if (vector.publicKey !== null) { + publicPromise = new Promise(function(resolve, reject) { + resolve(vector); + }); + } else { + publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithmName, namedCurve: vector.namedCurve}, false, publicKeyUsages) + .then(function(key) { + vector.publicKey = key; + return vector; + }); // Returns a copy of the sourceBuffer it is sent. + } + + if (vector.privateKey !== null) { + privatePromise = new Promise(function(resolve, reject) { + resolve(vector); + }); + } else { + privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithmName, namedCurve: vector.namedCurve}, false, privateKeyUsages) + .then(function(key) { + vector.privateKey = key; + return vector; + }); + } + + return Promise.all([publicPromise, privatePromise]); + } + + // Returns a copy of the sourceBuffer it is sent. + function copyBuffer(sourceBuffer) { + var source = new Uint8Array(sourceBuffer); + var copy = new Uint8Array(sourceBuffer.byteLength) + + for (var i=0; i 0) { + assert_false(equalBuffers(priorSignature, signature), "Two signings with a salt give different signatures") + } else { + assert_true(equalBuffers(priorSignature, signature), "Two signings with empty salt give same signature") + } + }, function(err) { + assert_unreached("second time verify error for test " + vector.name + ": '" + err.message + "'"); + }); + }, function(err) { + assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'"); + }); + }, vector.name + " round trip"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested signing or verifying + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " round trip"); + }); + + all_promises.push(promise); + }); + + + // Test signing with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var alteredVector = Object.assign({}, vector); + alteredVector.algorithm = Object.assign({}, vector.algorithm); + if (vector.algorithm.name === "RSA-PSS") { + alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5"; + } else { + alteredVector.algorithm.name = "RSA-PSS"; + } + + var promise = importVectorKeys(alteredVector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var operation = subtle.sign(vector.algorithm, alteredVector.privateKey, vector.plaintext) + .then(function(signature) { + assert_unreached("Signing should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " signing with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Test verification with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var alteredVector = Object.assign({}, vector); + alteredVector.algorithm = Object.assign({}, vector.algorithm); + if (vector.algorithm.name === "RSA-PSS") { + alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5"; + } else { + alteredVector.algorithm.name = "RSA-PSS"; + } + + var promise = importVectorKeys(alteredVector, ["verify"], ["sign"]) + .then(function(vectors) { + // Some tests are sign only + if (!("signature" in vector)) { + return; + } + promise_test(function(test) { + var operation = subtle.verify(vector.algorithm, alteredVector.publicKey, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_unreached("Verification should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Verification should fail with wrong signature + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure with altered signature"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure with altered signature"); + }); + + all_promises.push(promise); + }); + + // Verification should fail with wrong plaintext + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify"], ["sign"]) + .then(function(vectors) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": " + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure with altered plaintext"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure with altered plaintext"); + }); + + all_promises.push(promise); + }); + + + promise_test(function() { + return Promise.all(all_promises) + .then(function() {done();}) + .catch(function() {done();}) + }, "setup"); + + // A test vector has all needed fields for signing and verifying, EXCEPT that the + // key field may be null. This function replaces that null with the Correct + // CryptoKey object. + // + // Returns a Promise that yields an updated vector on success. + function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { + var publicPromise, privatePromise; + + if (vector.publicKey !== null) { + publicPromise = new Promise(function(resolve, reject) { + resolve(vector); + }); + } else { + publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, publicKeyUsages) + .then(function(key) { + vector.publicKey = key; + return vector; + }); // Returns a copy of the sourceBuffer it is sent. + } + + if (vector.privateKey !== null) { + privatePromise = new Promise(function(resolve, reject) { + resolve(vector); + }); + } else { + privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, privateKeyUsages) + .then(function(key) { + vector.privateKey = key; + return vector; + }); + } + + return Promise.all([publicPromise, privatePromise]); + } + + // Returns a copy of the sourceBuffer it is sent. + function copyBuffer(sourceBuffer) { + var source = new Uint8Array(sourceBuffer); + var copy = new Uint8Array(sourceBuffer.byteLength) + + for (var i=0; i 0) { + allNonemptySubsetsOf(remainingElements).forEach(function(combination) { + combination.push(firstElement); + results.push(combination); + }); + } + } + + return results; +} + + +// Create a string representation of keyGeneration parameters for +// test names and labels. +function objectToString(obj) { + var keyValuePairs = []; + + if (Array.isArray(obj)) { + return "[" + obj.map(function(elem){return objectToString(elem);}).join(", ") + "]"; + } else if (typeof obj === "object") { + Object.keys(obj).sort().forEach(function(keyName) { + keyValuePairs.push(keyName + ": " + objectToString(obj[keyName])); + }); + return "{" + keyValuePairs.join(", ") + "}"; + } else if (typeof obj === "undefined") { + return "undefined"; + } else { + return obj.toString(); + } + + var keyValuePairs = []; + + Object.keys(obj).sort().forEach(function(keyName) { + var value = obj[keyName]; + if (typeof value === "object") { + value = objectToString(value); + } else if (typeof value === "array") { + value = "[" + value.map(function(elem){return objectToString(elem);}).join(", ") + "]"; + } else { + value = value.toString(); + } + + keyValuePairs.push(keyName + ": " + value); + }); + + return "{" + keyValuePairs.join(", ") + "}"; +} + +// Is key a CryptoKey object with correct algorithm, extractable, and usages? +// Is it a secret, private, or public kind of key? +function assert_goodCryptoKey(key, algorithm, extractable, usages, kind) { + var correctUsages = []; + + var registeredAlgorithmName; + registeredAlgorithmNames.forEach(function(name) { + if (name.toUpperCase() === algorithm.name.toUpperCase()) { + registeredAlgorithmName = name; + } + }); + + assert_equals(key.constructor, CryptoKey, "Is a CryptoKey"); + assert_equals(key.type, kind, "Is a " + kind + " key"); + if (key.type === "public") { + extractable = true; // public keys are always extractable + } + assert_equals(key.extractable, extractable, "Extractability is correct"); + + assert_equals(key.algorithm.name, registeredAlgorithmName, "Correct algorithm name"); + assert_equals(key.algorithm.length, algorithm.length, "Correct length"); + if (["HMAC", "RSASSA-PKCS1-v1_5", "RSA-PSS"].includes(registeredAlgorithmName)) { + assert_equals(key.algorithm.hash.name.toUpperCase(), algorithm.hash.toUpperCase(), "Correct hash function"); + } + + // usages is expected to be provided for a key pair, but we are checking + // only a single key. The publicKey and privateKey portions of a key pair + // recognize only some of the usages appropriate for a key pair. + if (key.type === "public") { + ["encrypt", "verify", "wrapKey"].forEach(function(usage) { + if (usages.includes(usage)) { + correctUsages.push(usage); + } + }); + } else if (key.type === "private") { + ["decrypt", "sign", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) { + if (usages.includes(usage)) { + correctUsages.push(usage); + } + }); + } else { + correctUsages = usages; + } + + assert_equals((typeof key.usages), "object", key.type + " key.usages is an object"); + assert_not_equals(key.usages, null, key.type + " key.usages isn't null"); + + // The usages parameter could have repeats, but the usages + // property of the result should not. + var usageCount = 0; + key.usages.forEach(function(usage) { + usageCount += 1; + assert_in_array(usage, correctUsages, "Has " + usage + " usage"); + }); + assert_equals(key.usages.length, usageCount, "usages property is correct"); +} + + +// The algorithm parameter is an object with a name and other +// properties. Given the name, generate all valid parameters. +function allAlgorithmSpecifiersFor(algorithmName) { + var results = []; + + // RSA key generation is slow. Test a minimal set of parameters + var hashes = ["SHA-1", "SHA-256"]; + + // EC key generation is a lot faster. Check all curves in the spec + var curves = ["P-256", "P-384", "P-521"]; + + if (algorithmName.toUpperCase().substring(0, 3) === "AES") { + // Specifier properties are name and length + [128, 192, 256].forEach(function(length) { + results.push({name: algorithmName, length: length}); + }); + } else if (algorithmName.toUpperCase() === "HMAC") { + [ + {name: "SHA-1", length: 160}, + {name: "SHA-256", length: 256}, + {name: "SHA-384", length: 384}, + {name: "SHA-512", length: 512} + ].forEach(function(hashAlgorithm) { + results.push({name: algorithmName, hash: hashAlgorithm.name, length: hashAlgorithm.length}); + }); + } else if (algorithmName.toUpperCase().substring(0, 3) === "RSA") { + hashes.forEach(function(hashName) { + results.push({name: algorithmName, hash: hashName, modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])}); + }); + } else if (algorithmName.toUpperCase().substring(0, 2) === "EC") { + curves.forEach(function(curveName) { + results.push({name: algorithmName, namedCurve: curveName}); + }); + } + + return results; +} + + +// Create every possible valid usages parameter, given legal +// usages. Note that an empty usages parameter is not always valid. +// +// There is an optional parameter - mandatoryUsages. If provided, +// it should be an array containing those usages of which one must be +// included. +function allValidUsages(validUsages, emptyIsValid, mandatoryUsages) { + if (typeof mandatoryUsages === "undefined") { + mandatoryUsages = []; + } + + var okaySubsets = []; + allNonemptySubsetsOf(validUsages).forEach(function(subset) { + if (mandatoryUsages.length === 0) { + okaySubsets.push(subset); + } else { + for (var i=0; i x); + }); + } else if (signParams) { + var verifyKey; + return subtle.exportKey("jwk",expected) + .then(function(jwkExpectedKey){ + if (expected.algorithm.name === "RSA-PSS" || expected.algorithm.name === "RSASSA-PKCS1-v1_5") { + ["d","p","q","dp","dq","qi","oth"].forEach(function(field){ delete jwkExpectedKey[field]; }); + } + if (expected.algorithm.name === "ECDSA") { + delete jwkExpectedKey["d"]; + } + jwkExpectedKey.key_ops = ["verify"]; + return subtle.importKey("jwk", jwkExpectedKey, expected.algorithm, true, ["verify"]); + }).then(function(expectedVerifyKey){ + verifyKey = expectedVerifyKey; + return subtle.sign(signParams, got, new Uint8Array(32)); + }).then(function(signature){ + return subtle.verify(signParams, verifyKey, signature, new Uint8Array(32)); + }); + } else if (wrapParams) { + var aKeyToWrap, wrappedWithExpected; + return subtle.importKey("raw", new Uint8Array(16), "AES-CBC", true, ["encrypt"]) + .then(function(key){ + aKeyToWrap = key; + return subtle.wrapKey("raw", aKeyToWrap, expected, wrapParams); + }).then(function(wrapResult){ + wrappedWithExpected = Array.from((new Uint8Array(wrapResult)).values()); + return subtle.wrapKey("raw", aKeyToWrap, got, wrapParams); + }).then(function(wrapResult){ + var wrappedWithGot = Array.from((new Uint8Array(wrapResult)).values()); + return wrappedWithGot.every((x,i) => x === wrappedWithExpected[i]); + }); + } else { + var expectedDerivedBits; + return subtle.deriveBits(deriveParams, expected, 128) + .then(function(result){ + expectedDerivedBits = Array.from((new Uint8Array(result)).values()); + return subtle.deriveBits(deriveParams, got, 128); + }).then(function(result){ + var gotDerivedBits = Array.from((new Uint8Array(result)).values()); + return gotDerivedBits.every((x,i) => x === expectedDerivedBits[i]); + }); + } + } + + // Raw AES encryption + function aes( k, p ) { + return subtle.encrypt({name: "AES-CBC", iv: new Uint8Array(16) }, k, p).then(function(ciphertext){return ciphertext.slice(0,16);}); + } + + // AES Key Wrap + function aeskw(key, data) { + if (data.byteLength % 8 !== 0) { + throw new Error("AES Key Wrap data must be a multiple of 8 bytes in length"); + } + + var A = Uint8Array.from([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0, 0, 0, 0, 0, 0, 0, 0]), + Av = new DataView(A.buffer), + R = [], + n = data.byteLength / 8; + + for(var i = 0; i { // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` - const sabConstructor = new WebAssembly.Memory({ shared:true, initial:0, maximum:0 }).buffer.constructor; + let sabConstructor; + try { + sabConstructor = new WebAssembly.Memory({ shared:true, initial:0, maximum:0 }).buffer.constructor; + } catch(e) { + sabConstructor = null; + } return (type, length) => { if (type === "ArrayBuffer") { return new ArrayBuffer(length); } else if (type === "SharedArrayBuffer") { - if (sabConstructor.name !== "SharedArrayBuffer") { + if (sabConstructor && sabConstructor.name !== "SharedArrayBuffer") { throw new Error("WebAssembly.Memory does not support shared:true"); } return new sabConstructor(length); diff --git a/test/fixtures/wpt/common/window-name-setter.html b/test/fixtures/wpt/common/window-name-setter.html new file mode 100644 index 00000000000000..c0603aa300838b --- /dev/null +++ b/test/fixtures/wpt/common/window-name-setter.html @@ -0,0 +1,12 @@ + + +A page that sets window.name + + diff --git a/test/fixtures/wpt/dom/abort/AbortSignal.any.js b/test/fixtures/wpt/dom/abort/AbortSignal.any.js new file mode 100644 index 00000000000000..1d7d7678eb1a6e --- /dev/null +++ b/test/fixtures/wpt/dom/abort/AbortSignal.any.js @@ -0,0 +1,12 @@ +test(t => { + const signal = AbortSignal.abort(); + assert_true(signal instanceof AbortSignal, "returned object is an AbortSignal"); + assert_true(signal.aborted, "returned signal is already aborted"); +}, "the AbortSignal.abort() static returns an already aborted signal"); + +async_test(t => { + const s = AbortSignal.abort(); + s.addEventListener("abort", t.unreached_func("abort event listener called")); + s.onabort = t.unreached_func("abort event handler called"); + t.step_timeout(() => { t.done(); }, 2000); +}, "signal returned by AbortSignal.abort() should not fire abort event"); diff --git a/test/fixtures/wpt/dom/abort/event.any.js b/test/fixtures/wpt/dom/abort/event.any.js index 2589ba1ce45091..a67e6f400fcf1d 100644 --- a/test/fixtures/wpt/dom/abort/event.any.js +++ b/test/fixtures/wpt/dom/abort/event.any.js @@ -64,9 +64,4 @@ test(t => { controller.abort(); }, "the abort event should have the right properties"); -test(t => { - const signal = AbortSignal.abort(); - assert_true(signal.aborted); -}, "the AbortSignal.abort() static returns an already aborted signal"); - done(); diff --git a/test/fixtures/wpt/interfaces/WebCryptoAPI.idl b/test/fixtures/wpt/interfaces/WebCryptoAPI.idl new file mode 100644 index 00000000000000..d7fce62d5b0003 --- /dev/null +++ b/test/fixtures/wpt/interfaces/WebCryptoAPI.idl @@ -0,0 +1,236 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Web Cryptography API (https://w3c.github.io/webcrypto/) + +partial interface mixin WindowOrWorkerGlobalScope { + [SameObject] readonly attribute Crypto crypto; +}; + +[Exposed=(Window,Worker)] +interface Crypto { + [SecureContext] readonly attribute SubtleCrypto subtle; + ArrayBufferView getRandomValues(ArrayBufferView array); +}; + +typedef (object or DOMString) AlgorithmIdentifier; + +typedef AlgorithmIdentifier HashAlgorithmIdentifier; + +dictionary Algorithm { + required DOMString name; +}; + +dictionary KeyAlgorithm { + required DOMString name; +}; + +enum KeyType { "public", "private", "secret" }; + +enum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" }; + +[SecureContext,Exposed=(Window,Worker)] +interface CryptoKey { + readonly attribute KeyType type; + readonly attribute boolean extractable; + readonly attribute object algorithm; + readonly attribute object usages; +}; + +enum KeyFormat { "raw", "spki", "pkcs8", "jwk" }; + +[SecureContext,Exposed=(Window,Worker)] +interface SubtleCrypto { + Promise encrypt(AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource data); + Promise decrypt(AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource data); + Promise sign(AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource data); + Promise verify(AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource signature, + BufferSource data); + Promise digest(AlgorithmIdentifier algorithm, + BufferSource data); + + Promise generateKey(AlgorithmIdentifier algorithm, + boolean extractable, + sequence keyUsages ); + Promise deriveKey(AlgorithmIdentifier algorithm, + CryptoKey baseKey, + AlgorithmIdentifier derivedKeyType, + boolean extractable, + sequence keyUsages ); + Promise deriveBits(AlgorithmIdentifier algorithm, + CryptoKey baseKey, + unsigned long length); + + Promise importKey(KeyFormat format, + (BufferSource or JsonWebKey) keyData, + AlgorithmIdentifier algorithm, + boolean extractable, + sequence keyUsages ); + Promise exportKey(KeyFormat format, CryptoKey key); + + Promise wrapKey(KeyFormat format, + CryptoKey key, + CryptoKey wrappingKey, + AlgorithmIdentifier wrapAlgorithm); + Promise unwrapKey(KeyFormat format, + BufferSource wrappedKey, + CryptoKey unwrappingKey, + AlgorithmIdentifier unwrapAlgorithm, + AlgorithmIdentifier unwrappedKeyAlgorithm, + boolean extractable, + sequence keyUsages ); +}; + +dictionary RsaOtherPrimesInfo { + // The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms + DOMString r; + DOMString d; + DOMString t; +}; + +dictionary JsonWebKey { + // The following fields are defined in Section 3.1 of JSON Web Key + DOMString kty; + DOMString use; + sequence key_ops; + DOMString alg; + + // The following fields are defined in JSON Web Key Parameters Registration + boolean ext; + + // The following fields are defined in Section 6 of JSON Web Algorithms + DOMString crv; + DOMString x; + DOMString y; + DOMString d; + DOMString n; + DOMString e; + DOMString p; + DOMString q; + DOMString dp; + DOMString dq; + DOMString qi; + sequence oth; + DOMString k; +}; + +typedef Uint8Array BigInteger; + +dictionary CryptoKeyPair { + CryptoKey publicKey; + CryptoKey privateKey; +}; + +dictionary RsaKeyGenParams : Algorithm { + required [EnforceRange] unsigned long modulusLength; + required BigInteger publicExponent; +}; + +dictionary RsaHashedKeyGenParams : RsaKeyGenParams { + required HashAlgorithmIdentifier hash; +}; + +dictionary RsaKeyAlgorithm : KeyAlgorithm { + required unsigned long modulusLength; + required BigInteger publicExponent; +}; + +dictionary RsaHashedKeyAlgorithm : RsaKeyAlgorithm { + required KeyAlgorithm hash; +}; + +dictionary RsaHashedImportParams : Algorithm { + required HashAlgorithmIdentifier hash; +}; + +dictionary RsaPssParams : Algorithm { + required [EnforceRange] unsigned long saltLength; +}; + +dictionary RsaOaepParams : Algorithm { + BufferSource label; +}; + +dictionary EcdsaParams : Algorithm { + required HashAlgorithmIdentifier hash; +}; + +typedef DOMString NamedCurve; + +dictionary EcKeyGenParams : Algorithm { + required NamedCurve namedCurve; +}; + +dictionary EcKeyAlgorithm : KeyAlgorithm { + required NamedCurve namedCurve; +}; + +dictionary EcKeyImportParams : Algorithm { + required NamedCurve namedCurve; +}; + +dictionary EcdhKeyDeriveParams : Algorithm { + required CryptoKey public; +}; + +dictionary AesCtrParams : Algorithm { + required BufferSource counter; + required [EnforceRange] octet length; +}; + +dictionary AesKeyAlgorithm : KeyAlgorithm { + required unsigned short length; +}; + +dictionary AesKeyGenParams : Algorithm { + required [EnforceRange] unsigned short length; +}; + +dictionary AesDerivedKeyParams : Algorithm { + required [EnforceRange] unsigned short length; +}; + +dictionary AesCbcParams : Algorithm { + required BufferSource iv; +}; + +dictionary AesGcmParams : Algorithm { + required BufferSource iv; + BufferSource additionalData; + [EnforceRange] octet tagLength; +}; + +dictionary HmacImportParams : Algorithm { + required HashAlgorithmIdentifier hash; + [EnforceRange] unsigned long length; +}; + +dictionary HmacKeyAlgorithm : KeyAlgorithm { + required KeyAlgorithm hash; + required unsigned long length; +}; + +dictionary HmacKeyGenParams : Algorithm { + required HashAlgorithmIdentifier hash; + [EnforceRange] unsigned long length; +}; + +dictionary HkdfParams : Algorithm { + required HashAlgorithmIdentifier hash; + required BufferSource salt; + required BufferSource info; +}; + +dictionary Pbkdf2Params : Algorithm { + required BufferSource salt; + required [EnforceRange] unsigned long iterations; + required HashAlgorithmIdentifier hash; +}; diff --git a/test/fixtures/wpt/interfaces/performance-timeline.idl b/test/fixtures/wpt/interfaces/performance-timeline.idl new file mode 100644 index 00000000000000..d3a5a278055eba --- /dev/null +++ b/test/fixtures/wpt/interfaces/performance-timeline.idl @@ -0,0 +1,49 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Performance Timeline Level 2 (https://w3c.github.io/performance-timeline/) + +partial interface Performance { + PerformanceEntryList getEntries (); + PerformanceEntryList getEntriesByType (DOMString type); + PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type); +}; +typedef sequence PerformanceEntryList; + +[Exposed=(Window,Worker)] +interface PerformanceEntry { + readonly attribute DOMString name; + readonly attribute DOMString entryType; + readonly attribute DOMHighResTimeStamp startTime; + readonly attribute DOMHighResTimeStamp duration; + [Default] object toJSON(); +}; + +callback PerformanceObserverCallback = undefined (PerformanceObserverEntryList entries, + PerformanceObserver observer, + optional PerformanceObserverCallbackOptions options = {}); +[Exposed=(Window,Worker)] +interface PerformanceObserver { + constructor(PerformanceObserverCallback callback); + undefined observe (optional PerformanceObserverInit options = {}); + undefined disconnect (); + PerformanceEntryList takeRecords(); + [SameObject] static readonly attribute FrozenArray supportedEntryTypes; +}; + +dictionary PerformanceObserverCallbackOptions { + unsigned long long droppedEntriesCount; +}; + +dictionary PerformanceObserverInit { + sequence entryTypes; + DOMString type; + boolean buffered; +}; + +[Exposed=(Window,Worker)] +interface PerformanceObserverEntryList { + PerformanceEntryList getEntries(); + PerformanceEntryList getEntriesByType (DOMString type); + PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type); +}; diff --git a/test/fixtures/wpt/interfaces/user-timing.idl b/test/fixtures/wpt/interfaces/user-timing.idl new file mode 100644 index 00000000000000..28ee8aac2b19a6 --- /dev/null +++ b/test/fixtures/wpt/interfaces/user-timing.idl @@ -0,0 +1,34 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: User Timing Level 3 (https://w3c.github.io/user-timing/) + +dictionary PerformanceMarkOptions { + any detail; + DOMHighResTimeStamp startTime; +}; + +dictionary PerformanceMeasureOptions { + any detail; + (DOMString or DOMHighResTimeStamp) start; + DOMHighResTimeStamp duration; + (DOMString or DOMHighResTimeStamp) end; +}; + +partial interface Performance { + PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {}); + undefined clearMarks(optional DOMString markName); + PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark); + undefined clearMeasures(optional DOMString measureName); +}; + +[Exposed=(Window,Worker)] +interface PerformanceMark : PerformanceEntry { + constructor(DOMString markName, optional PerformanceMarkOptions markOptions = {}); + readonly attribute any detail; +}; + +[Exposed=(Window,Worker)] +interface PerformanceMeasure : PerformanceEntry { + readonly attribute any detail; +}; diff --git a/test/fixtures/wpt/performance-timeline/META.yml b/test/fixtures/wpt/performance-timeline/META.yml new file mode 100644 index 00000000000000..89fae1db0d9b7a --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/META.yml @@ -0,0 +1,4 @@ +spec: https://w3c.github.io/performance-timeline/ +suggested_reviewers: + - plehegar + - igrigorik diff --git a/test/fixtures/wpt/performance-timeline/buffered-flag-after-timeout.any.js b/test/fixtures/wpt/performance-timeline/buffered-flag-after-timeout.any.js new file mode 100644 index 00000000000000..08b3e323146585 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/buffered-flag-after-timeout.any.js @@ -0,0 +1,11 @@ +async_test(t => { + performance.mark('foo'); + t.step_timeout(() => { + // After a timeout, PerformanceObserver should still receive entry if using the buffered flag. + new PerformanceObserver(t.step_func_done(list => { + const entries = list.getEntries(); + assert_equals(entries.length, 1, 'There should be 1 mark entry.'); + assert_equals(entries[0].entryType, 'mark'); + })).observe({type: 'mark', buffered: true}); + }, 100); +}, 'PerformanceObserver with buffered flag sees entry after timeout'); diff --git a/test/fixtures/wpt/performance-timeline/buffered-flag-observer.any.js b/test/fixtures/wpt/performance-timeline/buffered-flag-observer.any.js new file mode 100644 index 00000000000000..31dc39c128ad55 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/buffered-flag-observer.any.js @@ -0,0 +1,15 @@ +async_test( t=> { + for (let i = 0; i < 50; i++) + performance.mark('foo' + i); + let marksCreated = 50; + let marksReceived = 0; + new PerformanceObserver(list => { + marksReceived += list.getEntries().length; + if (marksCreated < 100) { + performance.mark('bar' + marksCreated); + marksCreated++; + } + if (marksReceived == 100) + t.done(); + }).observe({type: 'mark', buffered: true}); +}, 'PerformanceObserver with buffered flag should see past and future entries.'); diff --git a/test/fixtures/wpt/performance-timeline/case-sensitivity.any.js b/test/fixtures/wpt/performance-timeline/case-sensitivity.any.js new file mode 100644 index 00000000000000..3a98505ae67f7d --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/case-sensitivity.any.js @@ -0,0 +1,64 @@ + test(function () { + assert_equals(typeof self.performance, "object"); + assert_equals(typeof self.performance.getEntriesByType, "function"); + var lowerList = self.performance.getEntriesByType("resource"); + var upperList = self.performance.getEntriesByType("RESOURCE"); + var mixedList = self.performance.getEntriesByType("ReSoUrCe"); + + assert_not_equals(lowerList.length, 0, "Resource entries exist"); + assert_equals(upperList.length, 0, "getEntriesByType('RESOURCE').length"); + assert_equals(mixedList.length, 0, "getEntriesByType('ReSoUrCe').length"); + + }, "getEntriesByType values are case sensitive"); + + test(function () { + assert_equals(typeof self.performance, "object"); + assert_equals(typeof self.performance.getEntriesByName, "function"); + var origin = self.location.protocol + "//" + self.location.host; + var location1 = origin.toUpperCase() + "/resources/testharness.js"; + var location2 = self.location.protocol + "//" + + self.location.host.toUpperCase() + "/resources/testharness.js"; + var lowerList = self.performance.getEntriesByName(origin + "/resources/testharness.js"); + var upperList = self.performance.getEntriesByName(location1); + var mixedList = self.performance.getEntriesByName(location2); + + assert_equals(lowerList.length, 1, "Resource entry exist"); + assert_equals(upperList.length, 0, "getEntriesByName('" + location1 + "').length"); + assert_equals(mixedList.length, 0, "getEntriesByName('" + location2 + "').length"); + + }, "getEntriesByName values are case sensitive"); + + async_test(function (t) { + // Test type/buffered case sensitivity. + observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + assert_unreached("Observer(type) should not be called."); + }) + ); + observer.observe({type: "Mark"}); + observer.observe({type: "Measure"}); + observer.observe({type: "MARK"}); + observer.observe({type: "MEASURE"}); + observer.observe({type: "Mark", buffered: true}); + observer.observe({type: "Measure", buffered: true}); + observer.observe({type: "MARK", buffered: true}); + observer.observe({type: "MEASURE", buffered: true}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); + + // Test entryTypes case sensitivity. + observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + assert_unreached("Observer(entryTypes) should not be called."); + }) + ); + observer.observe({entryTypes: ["Mark", "Measure"]}); + observer.observe({entryTypes: ["MARK", "MEASURE"]}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); + + t.step_timeout(function() { + t.done(); + }, 1000); + + }, "observe() and case sensitivity for types/entryTypes and buffered."); diff --git a/test/fixtures/wpt/performance-timeline/get-invalid-entries.html b/test/fixtures/wpt/performance-timeline/get-invalid-entries.html new file mode 100644 index 00000000000000..33d6589e275e26 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/get-invalid-entries.html @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/idlharness.any.js b/test/fixtures/wpt/performance-timeline/idlharness.any.js new file mode 100644 index 00000000000000..32efebe98ffd47 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/idlharness.any.js @@ -0,0 +1,25 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://w3c.github.io/performance-timeline/ + +'use strict'; + +idl_test( + ['performance-timeline'], + ['hr-time', 'dom'], + async idl_array => { + idl_array.add_objects({ + Performance: ['performance'], + PerformanceObserver: ['observer'], + PerformanceObserverEntryList: ['entryList'], + }); + + self.entryList = await new Promise((resolve, reject) => { + self.observer = new PerformanceObserver(resolve); + observer.observe({ entryTypes: ['mark'] }); + performance.mark('test'); + }); + } +); diff --git a/test/fixtures/wpt/performance-timeline/multiple-buffered-flag-observers.any.js b/test/fixtures/wpt/performance-timeline/multiple-buffered-flag-observers.any.js new file mode 100644 index 00000000000000..5dd44fb18fbdb9 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/multiple-buffered-flag-observers.any.js @@ -0,0 +1,32 @@ +promise_test(() => { + // The first promise waits for one buffered flag observer to receive 3 entries. + const promise1 = new Promise(resolve1 => { + let numObserved1 = 0; + new PerformanceObserver((entryList, obs) => { + // This buffered flag observer is constructed after a regular observer detects a mark. + new PerformanceObserver(list => { + numObserved1 += list.getEntries().length; + if (numObserved1 == 3) + resolve1(); + }).observe({type: 'mark', buffered: true}); + obs.disconnect(); + }).observe({entryTypes: ['mark']}); + performance.mark('foo'); + }); + // The second promise waits for another buffered flag observer to receive 3 entries. + const promise2 = new Promise(resolve2 => { + step_timeout(() => { + let numObserved2 = 0; + // This buffered flag observer is constructed after a delay of 100ms. + new PerformanceObserver(list => { + numObserved2 += list.getEntries().length; + if (numObserved2 == 3) + resolve2(); + }).observe({type: 'mark', buffered: true}); + }, 100); + performance.mark('bar'); + }); + performance.mark('meow'); + // Pass if and only if both buffered observers received all 3 mark entries. + return Promise.all([promise1, promise2]); +}, 'Multiple PerformanceObservers with buffered flag see all entries'); diff --git a/test/fixtures/wpt/performance-timeline/not-clonable.html b/test/fixtures/wpt/performance-timeline/not-clonable.html new file mode 100644 index 00000000000000..d651776e5f4b94 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-clonable.html @@ -0,0 +1,10 @@ + + + + + diff --git a/test/fixtures/wpt/performance-timeline/observer-buffered-false.any.js b/test/fixtures/wpt/performance-timeline/observer-buffered-false.any.js new file mode 100644 index 00000000000000..a28100b0fdba2e --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/observer-buffered-false.any.js @@ -0,0 +1,12 @@ +async_test(t => { + performance.mark('foo'); + // Use a timeout to ensure the remainder of the test runs after the entry is created. + t.step_timeout(() => { + // Observer with buffered flag set to false should not see entry. + new PerformanceObserver(() => { + assert_unreached('Should not have observed any entry!'); + }).observe({type: 'mark', buffered: false}); + // Use a timeout to give time to the observer. + t.step_timeout(t.step_func_done(() => {}), 100); + }, 0); +}, 'PerformanceObserver without buffered flag set to false cannot see past entries.'); diff --git a/test/fixtures/wpt/performance-timeline/performanceentry-tojson.any.js b/test/fixtures/wpt/performance-timeline/performanceentry-tojson.any.js new file mode 100644 index 00000000000000..44f0156eec1924 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/performanceentry-tojson.any.js @@ -0,0 +1,21 @@ +test(() => { + performance.mark('markName'); + performance.measure('measureName'); + + const entries = performance.getEntries(); + const performanceEntryKeys = [ + 'name', + 'entryType', + 'startTime', + 'duration' + ]; + for (let i = 0; i < entries.length; ++i) { + assert_equals(typeof(entries[i].toJSON), 'function'); + const json = entries[i].toJSON(); + assert_equals(typeof(json), 'object'); + for (const key of performanceEntryKeys) { + assert_equals(json[key], entries[i][key], + `entries[${i}].toJSON().${key} should match entries[${i}].${key}`); + } + } +}, 'Test toJSON() in PerformanceEntry'); diff --git a/test/fixtures/wpt/performance-timeline/performanceobservers.js b/test/fixtures/wpt/performance-timeline/performanceobservers.js new file mode 100644 index 00000000000000..3f357374efdfc2 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/performanceobservers.js @@ -0,0 +1,44 @@ +// Compares a performance entry to a predefined one +// perfEntriesToCheck is an array of performance entries from the user agent +// expectedEntries is an array of performance entries minted by the test +function checkEntries(perfEntriesToCheck, expectedEntries) { + function findMatch(pe) { + // we match based on entryType and name + for (var i = expectedEntries.length - 1; i >= 0; i--) { + var ex = expectedEntries[i]; + if (ex.entryType === pe.entryType && ex.name === pe.name) { + return ex; + } + } + return null; + } + + assert_equals(perfEntriesToCheck.length, expectedEntries.length, "performance entries must match"); + + perfEntriesToCheck.forEach(function (pe1) { + assert_not_equals(findMatch(pe1), null, "Entry matches"); + }); +} + +// Waits for performance.now to advance. Since precision reduction might +// cause it to return the same value across multiple calls. +function wait() { + var now = performance.now(); + while (now === performance.now()) + continue; +} + +// Ensure the entries list is sorted by startTime. +function checkSorted(entries) { + assert_not_equals(entries.length, 0, "entries list must not be empty"); + if (!entries.length) + return; + + var sorted = false; + var lastStartTime = entries[0].startTime; + for (var i = 1; i < entries.length; ++i) { + var currStartTime = entries[i].startTime; + assert_less_than_equal(lastStartTime, currStartTime, "entry list must be sorted by startTime"); + lastStartTime = currStartTime; + } +} diff --git a/test/fixtures/wpt/performance-timeline/po-callback-mutate.any.js b/test/fixtures/wpt/performance-timeline/po-callback-mutate.any.js new file mode 100644 index 00000000000000..8f1b09bc377120 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-callback-mutate.any.js @@ -0,0 +1,66 @@ +// META: script=performanceobservers.js + + async_test(function (t) { + var callbackCount = 0; + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + callbackCount++; + + if (callbackCount === 1) { + checkEntries(entryList.getEntries(), [ + {entryType: "measure", name: "measure1"}, + ]); + observer.observe({entryTypes: ["mark"]}); + self.performance.mark("mark2"); + self.performance.measure("measure2"); + return; + } + + if (callbackCount === 2) { + checkEntries(entryList.getEntries(), [ + {entryType: "mark", name: "mark2"}, + ]); + self.performance.mark("mark-before-change-observe-state-to-measure"); + self.performance.measure("measure-before-change-observe-state-to-measure"); + observer.observe({entryTypes: ["measure"]}); + self.performance.mark("mark3"); + self.performance.measure("measure3"); + return; + } + + if (callbackCount === 3) { + checkEntries(entryList.getEntries(), [ + {entryType: "measure", name: "measure3"}, + {entryType: "mark", name: "mark-before-change-observe-state-to-measure"}, + ]); + self.performance.mark("mark-before-change-observe-state-to-both"); + self.performance.measure("measure-before-change-observe-state-to-both"); + observer.observe({entryTypes: ["mark", "measure"]}); + self.performance.mark("mark4"); + self.performance.measure("measure4"); + return; + } + + if (callbackCount === 4) { + checkEntries(entryList.getEntries(), [ + {entryType: "measure", name: "measure-before-change-observe-state-to-both"}, + {entryType: "measure", name: "measure4"}, + {entryType: "mark", name: "mark4"}, + ]); + self.performance.mark("mark-before-disconnect"); + self.performance.measure("measure-before-disconnect"); + observer.disconnect(); + self.performance.mark("mark-after-disconnect"); + self.performance.measure("measure-after-disconnect"); + t.done(); + return; + } + + assert_unreached("The callback must not be invoked after disconnecting"); + }) + ); + + observer.observe({entryTypes: ["measure"]}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); + }, "PerformanceObserver modifications inside callback should update filtering and not clear buffer"); diff --git a/test/fixtures/wpt/performance-timeline/po-disconnect-removes-observed-types.any.js b/test/fixtures/wpt/performance-timeline/po-disconnect-removes-observed-types.any.js new file mode 100644 index 00000000000000..cac97bea0755c1 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-disconnect-removes-observed-types.any.js @@ -0,0 +1,19 @@ +// META: script=performanceobservers.js + +async_test(function (t) { + const observer = new PerformanceObserver( + t.step_func(function (entryList) { + // There should be no mark entry. + checkEntries(entryList.getEntries(), + [{ entryType: "measure", name: "b"}]); + t.done(); + }) + ); + observer.observe({type: "mark"}); + // Disconnect the observer. + observer.disconnect(); + // Now, only observe measure. + observer.observe({type: "measure"}); + performance.mark("a"); + performance.measure("b"); +}, "Types observed are forgotten when disconnect() is called."); diff --git a/test/fixtures/wpt/performance-timeline/po-disconnect.any.js b/test/fixtures/wpt/performance-timeline/po-disconnect.any.js new file mode 100644 index 00000000000000..5f5fb5aa43ba46 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-disconnect.any.js @@ -0,0 +1,37 @@ +// META: script=performanceobservers.js + + async_test(function (t) { + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + assert_unreached("This callback must not be invoked"); + }) + ); + observer.observe({entryTypes: ["mark", "measure", "navigation"]}); + observer.disconnect(); + self.performance.mark("mark1"); + self.performance.measure("measure1"); + t.step_timeout(function () { + t.done(); + }, 2000); + }, "disconnected callbacks must not be invoked"); + + test(function () { + var obs = new PerformanceObserver(function () { return true; }); + obs.disconnect(); + obs.disconnect(); + }, "disconnecting an unconnected observer is a no-op"); + + async_test(function (t) { + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + assert_unreached("This callback must not be invoked"); + }) + ); + observer.observe({entryTypes: ["mark"]}); + self.performance.mark("mark1"); + observer.disconnect(); + self.performance.mark("mark2"); + t.step_timeout(function () { + t.done(); + }, 2000); + }, "An observer disconnected after a mark must not have its callback invoked"); diff --git a/test/fixtures/wpt/performance-timeline/po-entries-sort.any.js b/test/fixtures/wpt/performance-timeline/po-entries-sort.any.js new file mode 100644 index 00000000000000..b0c781a3c0c03b --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-entries-sort.any.js @@ -0,0 +1,64 @@ +// META: script=performanceobservers.js + + async_test(function (t) { + var stored_entries = []; + var stored_entries_by_type = []; + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + + stored_entries = entryList.getEntries(); + stored_entries_by_type = entryList.getEntriesByType("mark"); + stored_entries_by_name = entryList.getEntriesByName("name-repeat"); + var startTimeOfMark2 = entryList.getEntriesByName("mark2")[0].startTime; + + checkSorted(stored_entries); + checkEntries(stored_entries, [ + {entryType: "measure", name: "measure1"}, + {entryType: "measure", name: "measure2"}, + {entryType: "measure", name: "measure3"}, + {entryType: "measure", name: "name-repeat"}, + {entryType: "mark", name: "mark1"}, + {entryType: "mark", name: "mark2"}, + {entryType: "measure", name: "measure-matching-mark2-1"}, + {entryType: "measure", name: "measure-matching-mark2-2"}, + {entryType: "mark", name: "name-repeat"}, + {entryType: "mark", name: "name-repeat"}, + ]); + + checkSorted(stored_entries_by_type); + checkEntries(stored_entries_by_type, [ + {entryType: "mark", name: "mark1"}, + {entryType: "mark", name: "mark2"}, + {entryType: "mark", name: "name-repeat"}, + {entryType: "mark", name: "name-repeat"}, + ]); + + checkSorted(stored_entries_by_name); + checkEntries(stored_entries_by_name, [ + {entryType: "measure", name: "name-repeat"}, + {entryType: "mark", name: "name-repeat"}, + {entryType: "mark", name: "name-repeat"}, + ]); + + observer.disconnect(); + t.done(); + }) + ); + + observer.observe({entryTypes: ["mark", "measure"]}); + + self.performance.mark("mark1"); + self.performance.measure("measure1"); + wait(); // Ensure mark1 !== mark2 startTime by making sure performance.now advances. + self.performance.mark("mark2"); + self.performance.measure("measure2"); + self.performance.measure("measure-matching-mark2-1", "mark2"); + wait(); // Ensure mark2 !== mark3 startTime by making sure performance.now advances. + self.performance.mark("name-repeat"); + self.performance.measure("measure3"); + self.performance.measure("measure-matching-mark2-2", "mark2"); + wait(); // Ensure name-repeat startTime will differ. + self.performance.mark("name-repeat"); + wait(); // Ensure name-repeat startTime will differ. + self.performance.measure("name-repeat"); + }, "getEntries, getEntriesByType, getEntriesByName sort order"); diff --git a/test/fixtures/wpt/performance-timeline/po-getentries.any.js b/test/fixtures/wpt/performance-timeline/po-getentries.any.js new file mode 100644 index 00000000000000..36169d5dbd6e0e --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-getentries.any.js @@ -0,0 +1,38 @@ +// META: script=performanceobservers.js + + async_test(function (t) { + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + checkEntries(entryList.getEntries(), + [{ entryType: "mark", name: "mark1"}], "getEntries"); + + checkEntries(entryList.getEntriesByType("mark"), + [{ entryType: "mark", name: "mark1"}], "getEntriesByType"); + assert_equals(entryList.getEntriesByType("measure").length, 0, + "getEntriesByType with no expected entry"); + assert_equals(entryList.getEntriesByType("234567").length, 0, + "getEntriesByType with no expected entry"); + + checkEntries(entryList.getEntriesByName("mark1"), + [{ entryType: "mark", name: "mark1"}], "getEntriesByName"); + assert_equals(entryList.getEntriesByName("mark2").length, 0, + "getEntriesByName with no expected entry"); + assert_equals(entryList.getEntriesByName("234567").length, 0, + "getEntriesByName with no expected entry"); + + checkEntries(entryList.getEntriesByName("mark1", "mark"), + [{ entryType: "mark", name: "mark1"}], "getEntriesByName with a type"); + assert_equals(entryList.getEntriesByName("mark1", "measure").length, 0, + "getEntriesByName with a type with no expected entry"); + assert_equals(entryList.getEntriesByName("mark2", "measure").length, 0, + "getEntriesByName with a type with no expected entry"); + assert_equals(entryList.getEntriesByName("mark1", "234567").length, 0, + "getEntriesByName with a type with no expected entry"); + + observer.disconnect(); + t.done(); + }) + ); + observer.observe({entryTypes: ["mark"]}); + self.performance.mark("mark1"); + }, "getEntries, getEntriesByType and getEntriesByName work"); diff --git a/test/fixtures/wpt/performance-timeline/po-mark-measure.any.js b/test/fixtures/wpt/performance-timeline/po-mark-measure.any.js new file mode 100644 index 00000000000000..0b205e094c75e1 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-mark-measure.any.js @@ -0,0 +1,61 @@ +// META: script=performanceobservers.js + + async_test(function (t) { + var stored_entries = []; + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + stored_entries = + stored_entries.concat(entryList.getEntries()); + if (stored_entries.length >= 4) { + checkEntries(stored_entries, + [{ entryType: "mark", name: "mark1"}, + { entryType: "mark", name: "mark2"}, + { entryType: "measure", name: "measure1"}, + { entryType: "measure", name: "measure2"}]); + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({entryTypes: ["mark", "measure"]}); + }, "entries are observable"); + + async_test(function (t) { + var mark_entries = []; + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + mark_entries = + mark_entries.concat(entryList.getEntries()); + if (mark_entries.length >= 2) { + checkEntries(mark_entries, + [{ entryType: "mark", name: "mark1"}, + { entryType: "mark", name: "mark2"}]); + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({entryTypes: ["mark"]}); + self.performance.mark("mark1"); + self.performance.mark("mark2"); + }, "mark entries are observable"); + + async_test(function (t) { + var measure_entries = []; + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + measure_entries = + measure_entries.concat(entryList.getEntries()); + if (measure_entries.length >= 2) { + checkEntries(measure_entries, + [{ entryType: "measure", name: "measure1"}, + { entryType: "measure", name: "measure2"}]); + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({entryTypes: ["measure"]}); + self.performance.measure("measure1"); + self.performance.measure("measure2"); + }, "measure entries are observable"); diff --git a/test/fixtures/wpt/performance-timeline/po-observe-repeated-type.any.js b/test/fixtures/wpt/performance-timeline/po-observe-repeated-type.any.js new file mode 100644 index 00000000000000..2bba396a6b69eb --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-observe-repeated-type.any.js @@ -0,0 +1,17 @@ +// META: script=performanceobservers.js + +async_test(function (t) { + const observer = new PerformanceObserver( + t.step_func(function (entryList) { + checkEntries(entryList.getEntries(), + [{ entryType: "mark", name: "early"}]); + observer.disconnect(); + t.done(); + }) + ); + performance.mark("early"); + // This call will not trigger anything. + observer.observe({type: "mark"}); + // This call should override the previous call and detect the early mark. + observer.observe({type: "mark", buffered: true}); +}, "Two calls of observe() with the same 'type' cause override."); diff --git a/test/fixtures/wpt/performance-timeline/po-observe-type.any.js b/test/fixtures/wpt/performance-timeline/po-observe-type.any.js new file mode 100644 index 00000000000000..b9854cc1466fa7 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-observe-type.any.js @@ -0,0 +1,64 @@ +// META: script=performanceobservers.js + +test(function () { + const obs = new PerformanceObserver(() => {}); + assert_throws_js(TypeError, function () { + obs.observe({}); + }); + assert_throws_js(TypeError, function () { + obs.observe({entryType: ['mark', 'measure']}); + }); +}, "Calling observe() without 'type' or 'entryTypes' throws a TypeError"); + +test(() => { + const obs = new PerformanceObserver(() =>{}); + obs.observe({entryTypes: ["mark"]}); + assert_throws_dom('InvalidModificationError', function () { + obs.observe({type: "measure"}); + }); +}, "Calling observe() with entryTypes and then type should throw an InvalidModificationError"); + +test(() => { + const obs = new PerformanceObserver(() =>{}); + obs.observe({type: "mark"}); + assert_throws_dom('InvalidModificationError', function () { + obs.observe({entryTypes: ["measure"]}); + }); +}, "Calling observe() with type and then entryTypes should throw an InvalidModificationError"); + +test(() => { + const obs = new PerformanceObserver(() =>{}); + assert_throws_js(TypeError, function () { + obs.observe({type: "mark", entryTypes: ["measure"]}); + }); +}, "Calling observe() with type and entryTypes should throw a TypeError"); + +test(function () { + const obs = new PerformanceObserver(() =>{}); + // Definitely not an entry type. + obs.observe({type: "this-cannot-match-an-entryType"}); + // Close to an entry type, but not quite. + obs.observe({type: "marks"}); +}, "Passing in unknown values to type does throw an exception."); + +async_test(function (t) { + let observedMark = false; + let observedMeasure = false; + const observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + observedMark |= entryList.getEntries().filter( + entry => entry.entryType === 'mark').length; + observedMeasure |= entryList.getEntries().filter( + entry => entry.entryType === 'measure').length + // Only conclude the test once we receive both entries! + if (observedMark && observedMeasure) { + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({type: "mark"}); + observer.observe({type: "measure"}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); +}, "observe() with different type values stacks."); diff --git a/test/fixtures/wpt/performance-timeline/po-observe.any.js b/test/fixtures/wpt/performance-timeline/po-observe.any.js new file mode 100644 index 00000000000000..5b593374baf157 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-observe.any.js @@ -0,0 +1,63 @@ +// META: script=performanceobservers.js + + test(function () { + const obs = new PerformanceObserver(() => {}); + assert_throws_js(TypeError, function () { + obs.observe({entryTypes: "mark"}); + }); + }, "entryTypes must be a sequence or throw a TypeError"); + + test(function () { + const obs = new PerformanceObserver(() => {}); + obs.observe({entryTypes: []}); + }, "Empty sequence entryTypes does not throw an exception."); + + test(function () { + const obs = new PerformanceObserver(() => {}); + obs.observe({entryTypes: ["this-cannot-match-an-entryType"]}); + obs.observe({entryTypes: ["marks","navigate", "resources"]}); + }, "Unknown entryTypes do not throw an exception."); + + test(function () { + const obs = new PerformanceObserver(() => {}); + obs.observe({entryTypes: ["mark","this-cannot-match-an-entryType"]}); + obs.observe({entryTypes: ["this-cannot-match-an-entryType","mark"]}); + obs.observe({entryTypes: ["mark"], others: true}); + }, "Filter unsupported entryType entryType names within the entryTypes sequence"); + + async_test(function (t) { + var finish = t.step_func(function () { t.done(); }); + var observer = new PerformanceObserver( + function (entryList, obs) { + var self = this; + t.step(function () { + assert_true(entryList instanceof PerformanceObserverEntryList, "first callback parameter must be a PerformanceObserverEntryList instance"); + assert_true(obs instanceof PerformanceObserver, "second callback parameter must be a PerformanceObserver instance"); + assert_equals(observer, self, "observer is the this value"); + assert_equals(observer, obs, "observer is second parameter"); + assert_equals(self, obs, "this and second parameter are the same"); + observer.disconnect(); + finish(); + }); + } + ); + self.performance.clearMarks(); + observer.observe({entryTypes: ["mark"]}); + self.performance.mark("mark1"); + }, "Check observer callback parameter and this values"); + + async_test(function (t) { + var observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + checkEntries(entryList.getEntries(), + [{ entryType: "measure", name: "measure1"}]); + observer.disconnect(); + t.done(); + }) + ); + self.performance.clearMarks(); + observer.observe({entryTypes: ["mark"]}); + observer.observe({entryTypes: ["measure"]}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); + }, "replace observer if already present"); diff --git a/test/fixtures/wpt/performance-timeline/po-observe.html b/test/fixtures/wpt/performance-timeline/po-observe.html new file mode 100644 index 00000000000000..a48f0f3764bda4 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-observe.html @@ -0,0 +1,86 @@ + + +PerformanceObservers: PerformanceObserverInit.buffered + + + + +

PerformanceObservers: PerformanceObserverInit.buffered

+

+PerformanceObserverInit.buffered should retrieve previously buffered entries +

+
+ diff --git a/test/fixtures/wpt/performance-timeline/po-resource.html b/test/fixtures/wpt/performance-timeline/po-resource.html new file mode 100644 index 00000000000000..00c173eeae921f --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-resource.html @@ -0,0 +1,48 @@ + + +PerformanceObservers: resource + + + +

PerformanceObservers: resource

+

+New resources will queue a PerformanceEntry. +

+
+ diff --git a/test/fixtures/wpt/performance-timeline/po-takeRecords.any.js b/test/fixtures/wpt/performance-timeline/po-takeRecords.any.js new file mode 100644 index 00000000000000..86ad397b0a5c37 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/po-takeRecords.any.js @@ -0,0 +1,34 @@ +// META: title=PerformanceObserver: takeRecords +// META: script=performanceobservers.js + +async_test(function (t) { + const observer = new PerformanceObserver(function (entryList, observer) { + assert_unreached('This callback should not have been called.') + }); + let entries = observer.takeRecords(); + checkEntries(entries, [], 'No records before observe'); + observer.observe({entryTypes: ['mark']}); + assert_equals(typeof(observer.takeRecords), 'function'); + entries = observer.takeRecords(); + checkEntries(entries, [], 'No records just from observe'); + performance.mark('a'); + performance.mark('b'); + entries = observer.takeRecords(); + checkEntries(entries, [ + {entryType: 'mark', name: 'a'}, + {entryType: 'mark', name: 'b'} + ]); + performance.mark('c'); + performance.mark('d'); + performance.mark('e'); + entries = observer.takeRecords(); + checkEntries(entries, [ + {entryType: 'mark', name: 'c'}, + {entryType: 'mark', name: 'd'}, + {entryType: 'mark', name: 'e'} + ]); + entries = observer.takeRecords(); + checkEntries(entries, [], 'No entries right after takeRecords'); + observer.disconnect(); + t.done(); + }, "Test PerformanceObserver's takeRecords()"); diff --git a/test/fixtures/wpt/performance-timeline/resources/postmessage-entry.html b/test/fixtures/wpt/performance-timeline/resources/postmessage-entry.html new file mode 100644 index 00000000000000..ef5be73395b49d --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/postmessage-entry.html @@ -0,0 +1,17 @@ + + diff --git a/test/fixtures/wpt/performance-timeline/resources/square.png b/test/fixtures/wpt/performance-timeline/resources/square.png new file mode 100644 index 00000000000000..be211bc3771803 Binary files /dev/null and b/test/fixtures/wpt/performance-timeline/resources/square.png differ diff --git a/test/fixtures/wpt/performance-timeline/resources/worker-invalid-entries.js b/test/fixtures/wpt/performance-timeline/resources/worker-invalid-entries.js new file mode 100644 index 00000000000000..bd7fba2ccf4b6a --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/worker-invalid-entries.js @@ -0,0 +1,6 @@ +performance.mark('workerMark'); +postMessage({ + 'invalid' : performance.getEntriesByType('invalid').length, + 'mark' : performance.getEntriesByType('mark').length, + 'measure' : performance.getEntriesByType('measure').length +}); diff --git a/test/fixtures/wpt/performance-timeline/resources/worker-with-performance-observer.js b/test/fixtures/wpt/performance-timeline/resources/worker-with-performance-observer.js new file mode 100644 index 00000000000000..a72fe81c47feac --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/worker-with-performance-observer.js @@ -0,0 +1,6 @@ +try { + new PerformanceObserver(() => true); + postMessage("SUCCESS"); +} catch (ex) { + postMessage("FAILURE"); +} diff --git a/test/fixtures/wpt/performance-timeline/supportedEntryTypes.any.js b/test/fixtures/wpt/performance-timeline/supportedEntryTypes.any.js new file mode 100644 index 00000000000000..25f195939e7b69 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/supportedEntryTypes.any.js @@ -0,0 +1,19 @@ +test(() => { + if (typeof PerformanceObserver.supportedEntryTypes === "undefined") + assert_unreached("supportedEntryTypes is not supported."); + const types = PerformanceObserver.supportedEntryTypes; + assert_greater_than(types.length, 0, + "There should be at least one entry in supportedEntryTypes."); + for (let i = 1; i < types.length; i++) { + assert_true(types[i-1] < types[i], + "The strings '" + types[i-1] + "' and '" + types[i] + + "' are repeated or they are not in alphabetical order.") + } +}, "supportedEntryTypes exists and returns entries in alphabetical order"); + +test(() => { + if (typeof PerformanceObserver.supportedEntryTypes === "undefined") + assert_unreached("supportedEntryTypes is not supported."); + assert_true(PerformanceObserver.supportedEntryTypes === + PerformanceObserver.supportedEntryTypes); +}, "supportedEntryTypes caches result"); diff --git a/test/fixtures/wpt/performance-timeline/webtiming-resolution.any.js b/test/fixtures/wpt/performance-timeline/webtiming-resolution.any.js new file mode 100644 index 00000000000000..d869c7c52d55d6 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/webtiming-resolution.any.js @@ -0,0 +1,25 @@ +function testTimeResolution(highResTimeFunc, funcString) { + test(() => { + const t0 = highResTimeFunc(); + let t1 = highResTimeFunc(); + while (t0 == t1) { + t1 = highResTimeFunc(); + } + const epsilon = 1e-5; + assert_greater_than_equal(t1 - t0, 0.005 - epsilon, 'The second ' + funcString + ' should be much greater than the first'); + }, 'Verifies the resolution of ' + funcString + ' is at least 5 microseconds.'); +} + +function timeByPerformanceNow() { + return performance.now(); +} + +function timeByUserTiming() { + performance.mark('timer'); + const time = performance.getEntriesByName('timer')[0].startTime; + performance.clearMarks('timer'); + return time; +} + +testTimeResolution(timeByPerformanceNow, 'performance.now()'); +testTimeResolution(timeByUserTiming, 'entry.startTime'); diff --git a/test/fixtures/wpt/performance-timeline/worker-with-performance-observer.html b/test/fixtures/wpt/performance-timeline/worker-with-performance-observer.html new file mode 100644 index 00000000000000..fc92bc971003f2 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/worker-with-performance-observer.html @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/resources/check-layout-th.js b/test/fixtures/wpt/resources/check-layout-th.js index 5d4236d1cedb0e..a507a8dfd7f197 100644 --- a/test/fixtures/wpt/resources/check-layout-th.js +++ b/test/fixtures/wpt/resources/check-layout-th.js @@ -36,6 +36,7 @@ function checkDataKeys(node) { "data-expected-scroll-width", "data-expected-scroll-height", "data-expected-bounding-client-rect-width", + "data-expected-bounding-client-rect-height", "data-total-x", "data-total-y", "data-expected-display", @@ -107,6 +108,11 @@ function checkExpectedValues(t, node, prefix) assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width"); } + var expectedHeight = checkAttribute(output, node, "data-expected-bounding-client-rect-height"); + if (expectedHeight) { + assert_tolerance(node.getBoundingClientRect().height, expectedHeight, prefix + "getBoundingClientRect().height"); + } + var expectedOffset = checkAttribute(output, node, "data-total-x"); if (expectedOffset) { var totalLeft = node.clientLeft + node.offsetLeft; diff --git a/test/fixtures/wpt/resources/idlharness.js b/test/fixtures/wpt/resources/idlharness.js index 76131e7c9602b9..d81693d2a2226d 100644 --- a/test/fixtures/wpt/resources/idlharness.js +++ b/test/fixtures/wpt/resources/idlharness.js @@ -1,13 +1,3 @@ -/* -Distributed under both the W3C Test Suite License [1] and the W3C -3-clause BSD License [2]. To contribute to a W3C Test Suite, see the -policies and contribution forms [3]. - -[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license -[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license -[3] http://www.w3.org/2004/10/27-testcases -*/ - /* For user documentation see docs/_writing-tests/idlharness.md */ /** @@ -101,6 +91,16 @@ function globalOf(func) return self; } +// https://esdiscuss.org/topic/isconstructor#content-11 +function isConstructor(o) { + try { + new (new Proxy(o, {construct: () => ({})})); + return true; + } catch(e) { + return false; + } +} + function throwOrReject(a_test, operation, fn, obj, args, message, cb) { if (operation.idlType.generic !== "Promise") { @@ -131,17 +131,6 @@ function awaitNCallbacks(n, cb, ctx) }; } -var fround = -(function(){ - if (Math.fround) return Math.fround; - - var arr = new Float32Array(1); - return function fround(n) { - arr[0] = n; - return arr[0]; - }; -})(); - /// IdlHarnessError /// // Entry point self.IdlHarnessError = function(message) @@ -185,31 +174,15 @@ self.IdlArray = function() /** * When adding multiple collections of IDLs one at a time, an earlier one - * might contain a partial interface or implements statement that depends + * might contain a partial interface or includes statement that depends * on a later one. Save these up and handle them right before we run * tests. * - * .partials is simply an array of objects from WebIDLParser.js' - * "partialinterface" production. .implements maps strings to arrays of - * strings, such that - * - * A implements B; - * A implements C; - * D implements E; - * - * results in this["implements"] = { A: ["B", "C"], D: ["E"] }. - * - * Similarly, - * - * interface A : B {}; - * interface B : C {}; - * - * results in this["inheritance"] = { A: "B", B: "C" } + * Both this.partials and this.includes will be the objects as parsed by + * WebIDLParser.js, not wrapped in IdlInterface or similar. */ this.partials = []; - this["implements"] = {}; - this["includes"] = {}; - this["inheritance"] = {}; + this.includes = []; /** * Record of skipped IDL items, in case we later realize that they are a @@ -261,15 +234,15 @@ IdlArray.prototype.internal_add_dependency_idls = function(parsed_idls, options) const new_options = { only: [] } const all_deps = new Set(); - Object.values(this.inheritance).forEach(v => all_deps.add(v)); - Object.entries(this.implements).forEach(([k, v]) => { - all_deps.add(k); - all_deps.add(v); + Object.values(this.members).forEach(v => { + if (v.base) { + all_deps.add(v.base); + } }); - // NOTE: If 'A includes B' for B that we care about, then A is also a dep. - Object.keys(this.includes).forEach(k => { - all_deps.add(k); - this.includes[k].forEach(v => all_deps.add(v)); + // Add both 'A' and 'B' for each 'A includes B' entry. + this.includes.forEach(i => { + all_deps.add(i.target); + all_deps.add(i.includes); }); this.partials.forEach(p => all_deps.add(p.name)); // Add 'TypeOfType' for each "typedef TypeOfType MyType;" entry. @@ -328,9 +301,6 @@ IdlArray.prototype.internal_add_dependency_idls = function(parsed_idls, options) var deps = []; if (parsed.name) { deps.push(parsed.name); - } else if (parsed.type === "implements") { - deps.push(parsed.target); - deps.push(parsed.implements); } else if (parsed.type === "includes") { deps.push(parsed.target); deps.push(parsed.includes); @@ -358,7 +328,7 @@ IdlArray.prototype.internal_add_dependency_idls = function(parsed_idls, options) } const follow_up = new Set(); - for (const dep_type of ["inheritance", "implements", "includes"]) { + for (const dep_type of ["inheritance", "includes"]) { if (parsed[dep_type]) { const inheriting = parsed[dep_type]; const inheritor = parsed.name || parsed.target; @@ -447,31 +417,13 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) return; } - if (parsed_idl.type == "implements") - { - if (should_skip(parsed_idl.target)) - { - return; - } - if (!(parsed_idl.target in this["implements"])) - { - this["implements"][parsed_idl.target] = []; - } - this["implements"][parsed_idl.target].push(parsed_idl["implements"]); - return; - } - if (parsed_idl.type == "includes") { if (should_skip(parsed_idl.target)) { return; } - if (!(parsed_idl.target in this["includes"])) - { - this["includes"][parsed_idl.target] = []; - } - this["includes"][parsed_idl.target].push(parsed_idl["includes"]); + this.includes.push(parsed_idl); return; } @@ -485,16 +437,6 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) throw new IdlHarnessError("Duplicate identifier " + parsed_idl.name); } - if (parsed_idl["inheritance"]) { - // NOTE: Clash should be impossible (would require redefinition of parsed_idl.name). - if (parsed_idl.name in this["inheritance"] - && parsed_idl["inheritance"] != this["inheritance"][parsed_idl.name]) { - throw new IdlHarnessError( - `Inheritance for ${parsed_idl.name} was already defined`); - } - this["inheritance"][parsed_idl.name] = parsed_idl["inheritance"]; - } - switch(parsed_idl.type) { case "interface": @@ -562,62 +504,6 @@ IdlArray.prototype.prevent_multiple_testing = function(name) this.members[name].prevent_multiple_testing = true; }; -IdlArray.prototype.recursively_get_implements = function(interface_name) -{ - /** - * Helper function for test(). Returns an array of things that implement - * interface_name, so if the IDL contains - * - * A implements B; - * B implements C; - * B implements D; - * - * then recursively_get_implements("A") should return ["B", "C", "D"]. - */ - var ret = this["implements"][interface_name]; - if (ret === undefined) - { - return []; - } - for (var i = 0; i < this["implements"][interface_name].length; i++) - { - ret = ret.concat(this.recursively_get_implements(ret[i])); - if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) - { - throw new IdlHarnessError("Circular implements statements involving " + ret[i]); - } - } - return ret; -}; - -IdlArray.prototype.recursively_get_includes = function(interface_name) -{ - /** - * Helper function for test(). Returns an array of things that implement - * interface_name, so if the IDL contains - * - * A includes B; - * B includes C; - * B includes D; - * - * then recursively_get_includes("A") should return ["B", "C", "D"]. - */ - var ret = this["includes"][interface_name]; - if (ret === undefined) - { - return []; - } - for (var i = 0; i < this["includes"][interface_name].length; i++) - { - ret = ret.concat(this.recursively_get_includes(ret[i])); - if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) - { - throw new IdlHarnessError("Circular includes statements involving " + ret[i]); - } - } - return ret; -}; - IdlArray.prototype.is_json_type = function(type) { /** @@ -678,6 +564,8 @@ IdlArray.prototype.is_json_type = function(type) case "Uint16Array": case "Uint32Array": case "Uint8ClampedArray": + case "BigInt64Array": + case "BigUint64Array": case "Float32Array": case "Float64Array": case "ArrayBuffer": @@ -695,25 +583,23 @@ IdlArray.prototype.is_json_type = function(type) // dictionaries where all of their members are JSON types if (thing instanceof IdlDictionary) { - var stack = thing.get_inheritance_stack(); - var map = new Map(); - while (stack.length) - { - stack.pop().members.forEach(function(m) { - map.set(m.name, m.idlType) - }); + const map = new Map(); + for (const dict of thing.get_reverse_inheritance_stack()) { + for (const m of dict.members) { + map.set(m.name, m.idlType); + } } return Array.from(map.values()).every(this.is_json_type, this); } // interface types that have a toJSON operation declared on themselves or - // one of their inherited or consequential interfaces. + // one of their inherited interfaces. if (thing instanceof IdlInterface) { var base; while (thing) { if (thing.has_to_json_regular_operation()) { return true; } - var mixins = this.implements[thing.name] || this.includes[thing.name]; + var mixins = this.includes[thing.name]; if (mixins) { mixins = mixins.map(function(id) { var mixin = this.members[id]; @@ -766,7 +652,7 @@ function exposure_set(object, default_set) { } function exposed_in(globals) { - if ('document' in self) { + if ('Window' in self) { return globals.has("Window"); } if ('DedicatedWorkerGlobalScope' in self && @@ -813,66 +699,9 @@ IdlArray.prototype.test = function() { /** Entry point. See documentation at beginning of file. */ - // First merge in all the partial interfaces and implements statements we - // encountered. - this.collapse_partials(); - - for (var lhs in this["implements"]) - { - this.recursively_get_implements(lhs).forEach(function(rhs) - { - var errStr = lhs + " implements " + rhs + ", but "; - if (!(lhs in this.members)) throw errStr + lhs + " is undefined."; - if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface."; - if (!(rhs in this.members)) throw errStr + rhs + " is undefined."; - if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface."; - - if (this.members[rhs].members.length) { - test(function () { - var clash = this.members[rhs].members.find(function(member) { - return this.members[lhs].members.find(function(m) { - return this.are_duplicate_members(m, member); - }.bind(this)); - }.bind(this)); - this.members[rhs].members.forEach(function(member) { - this.members[lhs].members.push(new IdlInterfaceMember(member)); - }.bind(this)); - assert_true(!clash, "member " + (clash && clash.name) + " is unique"); - }.bind(this), lhs + " implements " + rhs + ": member names are unique"); - } - }.bind(this)); - } - this["implements"] = {}; - - for (var lhs in this["includes"]) - { - this.recursively_get_includes(lhs).forEach(function(rhs) - { - var errStr = lhs + " includes " + rhs + ", but "; - if (!(lhs in this.members)) throw errStr + lhs + " is undefined."; - if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface."; - if (!(rhs in this.members)) throw errStr + rhs + " is undefined."; - if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface."; - - if (this.members[rhs].members.length) { - test(function () { - var clash = this.members[rhs].members.find(function(member) { - return this.members[lhs].members.find(function(m) { - return this.are_duplicate_members(m, member); - }.bind(this)); - }.bind(this)); - this.members[rhs].members.forEach(function(member) { - assert_true( - this.members[lhs].members.every(m => !this.are_duplicate_members(m, member)), - "member " + member.name + " is unique"); - this.members[lhs].members.push(new IdlInterfaceMember(member)); - }.bind(this)); - assert_true(!clash, "member " + (clash && clash.name) + " is unique"); - }.bind(this), lhs + " includes " + rhs + ": member names are unique"); - } - }.bind(this)); - } - this["includes"] = {}; + // First merge in all partial definitions and interface mixins. + this.merge_partials(); + this.merge_mixins(); // Assert B defined for A : B for (const member of Object.values(this.members).filter(m => m.base)) { @@ -886,7 +715,7 @@ IdlArray.prototype.test = function() if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`); } // Check for circular dependencies. - member.get_inheritance_stack(); + member.get_reverse_inheritance_stack(); } Object.getOwnPropertyNames(this.members).forEach(function(memberName) { @@ -921,7 +750,7 @@ IdlArray.prototype.test = function() } }; -IdlArray.prototype.collapse_partials = function() +IdlArray.prototype.merge_partials = function() { const testedPartials = new Map(); this.partials.forEach(function(parsed_idl) @@ -1015,6 +844,39 @@ IdlArray.prototype.collapse_partials = function() this.partials = []; } +IdlArray.prototype.merge_mixins = function() +{ + for (const parsed_idl of this.includes) + { + const lhs = parsed_idl.target; + const rhs = parsed_idl.includes; + + var errStr = lhs + " includes " + rhs + ", but "; + if (!(lhs in this.members)) throw errStr + lhs + " is undefined."; + if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface."; + if (!(rhs in this.members)) throw errStr + rhs + " is undefined."; + if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface."; + + if (this.members[rhs].members.length) { + test(function () { + var clash = this.members[rhs].members.find(function(member) { + return this.members[lhs].members.find(function(m) { + return this.are_duplicate_members(m, member); + }.bind(this)); + }.bind(this)); + this.members[rhs].members.forEach(function(member) { + assert_true( + this.members[lhs].members.every(m => !this.are_duplicate_members(m, member)), + "member " + member.name + " is unique"); + this.members[lhs].members.push(new IdlInterfaceMember(member)); + }.bind(this)); + assert_true(!clash, "member " + (clash && clash.name) + " is unique"); + }.bind(this), lhs + " includes " + rhs + ": member names are unique"); + } + } + this.includes = []; +} + IdlArray.prototype.are_duplicate_members = function(m1, m2) { if (m1.name !== m2.name) { return false; @@ -1116,7 +978,7 @@ IdlArray.prototype.assert_type_is = function(value, type) switch(type) { - case "void": + case "undefined": assert_equals(value, undefined); return; @@ -1172,7 +1034,7 @@ IdlArray.prototype.assert_type_is = function(value, type) case "float": assert_equals(typeof value, "number"); - assert_equals(value, fround(value), "float rounded to 32-bit float should be itself"); + assert_equals(value, Math.fround(value), "float rounded to 32-bit float should be itself"); assert_not_equals(value, Infinity); assert_not_equals(value, -Infinity); assert_not_equals(value, NaN); @@ -1188,7 +1050,7 @@ IdlArray.prototype.assert_type_is = function(value, type) case "unrestricted float": assert_equals(typeof value, "number"); - assert_equals(value, fround(value), "unrestricted float rounded to 32-bit float should be itself"); + assert_equals(value, Math.fround(value), "unrestricted float rounded to 32-bit float should be itself"); return; case "unrestricted double": @@ -1236,11 +1098,11 @@ IdlArray.prototype.assert_type_is = function(value, type) // We don't want to run the full // IdlInterface.prototype.test_instance_of, because that could result // in an infinite loop. TODO: This means we don't have tests for - // NoInterfaceObject interfaces, and we also can't test objects that - // come from another self. + // LegacyNoInterfaceObject interfaces, and we also can't test objects + // that come from another self. assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function"); if (value instanceof Object - && !this.members[type].has_extended_attribute("NoInterfaceObject") + && !this.members[type].has_extended_attribute("LegacyNoInterfaceObject") && type in self) { assert_true(value instanceof self[type], "instanceof " + type); @@ -1314,8 +1176,8 @@ function IdlDictionary(obj) IdlDictionary.prototype = Object.create(IdlObject.prototype); -IdlDictionary.prototype.get_inheritance_stack = function() { - return IdlInterface.prototype.get_inheritance_stack.call(this); +IdlDictionary.prototype.get_reverse_inheritance_stack = function() { + return IdlInterface.prototype.get_reverse_inheritance_stack.call(this); }; /// IdlInterface /// @@ -1415,10 +1277,10 @@ IdlInterface.prototype.should_have_interface_object = function() // environment and: // * is a callback interface that has constants declared on it, or // * is a non-callback interface that is not declared with the - // [NoInterfaceObject] extended attribute, + // [LegacyNoInterfaceObject] extended attribute, // a corresponding property MUST exist on the ECMAScript global object. - return this.is_callback() ? this.has_constants() : !this.has_extended_attribute("NoInterfaceObject"); + return this.is_callback() ? this.has_constants() : !this.has_extended_attribute("LegacyNoInterfaceObject"); }; IdlInterface.prototype.assert_interface_object_exists = function() @@ -1429,7 +1291,7 @@ IdlInterface.prototype.assert_interface_object_exists = function() IdlInterface.prototype.get_interface_object = function() { if (!this.should_have_interface_object()) { - var reason = this.is_callback() ? "lack of declared constants" : "declared [NoInterfaceObject] attribute"; + var reason = this.is_callback() ? "lack of declared constants" : "declared [LegacyNoInterfaceObject] attribute"; throw new IdlHarnessError(this.name + " has no interface object due to " + reason); } @@ -1457,39 +1319,39 @@ IdlInterface.prototype.has_default_to_json_regular_operation = function() { }); }; -IdlInterface.prototype.get_inheritance_stack = function() { - /** - * See https://heycam.github.io/webidl/#create-an-inheritance-stack - * - * Returns an array of IdlInterface objects which contains itself - * and all of its inherited interfaces. - * - * So given: - * - * A : B {}; - * B : C {}; - * C {}; - * - * then A.get_inheritance_stack() should return [A, B, C], - * and B.get_inheritance_stack() should return [B, C]. - * - * Note: as dictionary inheritance is expressed identically by the AST, - * this works just as well for getting a stack of inherited dictionaries. - */ - - var stack = [this]; - var idl_interface = this; +/** + * Implementation of https://heycam.github.io/webidl/#create-an-inheritance-stack + * with the order reversed. + * + * The order is reversed so that the base class comes first in the list, because + * this is what all call sites need. + * + * So given: + * + * A : B {}; + * B : C {}; + * C {}; + * + * then A.get_reverse_inheritance_stack() returns [C, B, A], + * and B.get_reverse_inheritance_stack() returns [C, B]. + * + * Note: as dictionary inheritance is expressed identically by the AST, + * this works just as well for getting a stack of inherited dictionaries. + */ +IdlInterface.prototype.get_reverse_inheritance_stack = function() { + const stack = [this]; + let idl_interface = this; while (idl_interface.base) { - var base = this.array.members[idl_interface.base]; + const base = this.array.members[idl_interface.base]; if (!base) { throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")"); } else if (stack.indexOf(base) > -1) { - stack.push(base); - let dep_chain = stack.map(i => i.name).join(','); + stack.unshift(base); + const dep_chain = stack.map(i => i.name).join(','); throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`); } idl_interface = base; - stack.push(idl_interface); + stack.unshift(idl_interface); } return stack; }; @@ -1503,76 +1365,27 @@ IdlInterface.prototype.get_inheritance_stack = function() { * for inclusion in the default toJSON operation for easy * comparison with actual value */ -IdlInterface.prototype.default_to_json_operation = function(callback) { - var map = new Map(), isDefault = false; - this.traverse_inherited_and_consequential_interfaces(function(I) { +IdlInterface.prototype.default_to_json_operation = function() { + const map = new Map() + let isDefault = false; + for (const I of this.get_reverse_inheritance_stack()) { if (I.has_default_to_json_regular_operation()) { isDefault = true; - I.members.forEach(function(m) { + for (const m of I.members) { if (m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) { map.set(m.name, m.idlType); } - }); + } } else if (I.has_to_json_regular_operation()) { isDefault = false; } - }); - return isDefault ? map : null; -}; - -/** - * Traverses inherited interfaces from the top down - * and imeplemented interfaces inside out. - * Invokes |callback| on each interface. - * - * This is an abstract implementation of the traversal - * algorithm specified in: - * https://heycam.github.io/webidl/#collect-attribute-values - * Given the following inheritance tree: - * - * F - * | - * C E - I - * | | - * B - D - * | - * G - A - H - J - * - * Invoking traverse_inherited_and_consequential_interfaces() on A - * would traverse the tree in the following order: - * C -> B -> F -> E -> I -> D -> A -> G -> H -> J - */ - -IdlInterface.prototype.traverse_inherited_and_consequential_interfaces = function(callback) { - if (typeof callback != "function") { - throw new TypeError(); } - var stack = this.get_inheritance_stack(); - _traverse_inherited_and_consequential_interfaces(stack, callback); + return isDefault ? map : null; }; -function _traverse_inherited_and_consequential_interfaces(stack, callback) { - var I = stack.pop(); - callback(I); - var mixins = I.array["implements"][I.name] || I.array["includes"][I.name]; - if (mixins) { - mixins.forEach(function(id) { - var mixin = I.array.members[id]; - if (!mixin) { - throw new Error("Interface " + id + " not found (implemented by " + I.name + ")"); - } - var interfaces = mixin.get_inheritance_stack(); - _traverse_inherited_and_consequential_interfaces(interfaces, callback); - }); - } - if (stack.length > 0) { - _traverse_inherited_and_consequential_interfaces(stack, callback); - } -} - IdlInterface.prototype.test = function() { - if (this.has_extended_attribute("NoInterfaceObject") || this.is_mixin()) + if (this.has_extended_attribute("LegacyNoInterfaceObject") || this.is_mixin()) { // No tests to do without an instance. TODO: We should still be able // to run tests on the prototype object, if we obtain one through some @@ -1580,10 +1393,16 @@ IdlInterface.prototype.test = function() return; } - if (!this.exposed) { - subsetTestByKey(this.name, test, function() { - assert_false(this.name in self); - }.bind(this), this.name + " interface: existence and properties of interface object"); + // If the interface object is not exposed, only test that. Members can't be + // tested either, but objects could still be tested in |test_object|. + if (!this.exposed) + { + if (!this.untested) + { + subsetTestByKey(this.name, test, function() { + assert_false(this.name in self); + }.bind(this), this.name + " interface: existence and properties of interface object"); + } return; } @@ -1603,23 +1422,16 @@ IdlInterface.prototype.test = function() this.test_members(); }; -// This supports both Constructor extended attributes and constructor -// operations until all idl fragments have been updated. IdlInterface.prototype.constructors = function() { - var extendedAttributes = this.extAttrs - .filter(function(attr) { return attr.name == "Constructor"; }); - var operations = this.members + return this.members .filter(function(m) { return m.type == "constructor"; }); - return extendedAttributes.concat(operations); } IdlInterface.prototype.test_self = function() { subsetTestByKey(this.name, test, function() { - // This function tests WebIDL as of 2015-01-13. - if (!this.should_have_interface_object()) { return; } @@ -1661,8 +1473,6 @@ IdlInterface.prototype.test_self = function() // "* Its [[Construct]] internal property is set as described in // ECMA-262 section 19.2.2.3." - // Tested below if no constructor is defined. TODO: test constructors - // if defined. // "* Its @@hasInstance property is set as described in ECMA-262 // section 19.2.3.8, unless otherwise specified." @@ -1681,7 +1491,7 @@ IdlInterface.prototype.test_self = function() // value of [[Prototype]] is the interface object for that other // interface." var inherited_interface = this.array.members[this.base]; - if (!inherited_interface.has_extended_attribute("NoInterfaceObject")) { + if (!inherited_interface.has_extended_attribute("LegacyNoInterfaceObject")) { inherited_interface.assert_interface_object_exists(); assert_equals(prototype, inherited_interface.get_interface_object(), 'prototype of ' + this.name + ' is not ' + @@ -1695,12 +1505,12 @@ IdlInterface.prototype.test_self = function() "prototype of self's property " + format_value(this.name) + " is not Function.prototype"); } + // Always test for [[Construct]]: + // https://github.com/heycam/webidl/issues/698 + assert_true(isConstructor(this.get_interface_object()), "interface object must pass IsConstructor check"); + if (!this.constructors().length) { - // "The internal [[Call]] method of the interface object behaves as - // follows . . . - // - // "If I was not declared with a [Constructor] extended attribute, - // then throw a TypeError." + // "If I was not declared with a constructor operation, then throw a TypeError." var interface_object = this.get_interface_object(); assert_throws_js(globalOf(interface_object).TypeError, function() { interface_object(); @@ -1773,7 +1583,7 @@ IdlInterface.prototype.test_self = function() if (!this.exposureSet.has("Window")) { throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window"); } - // TODO: when testing of [NoInterfaceObject] interfaces is supported, + // TODO: when testing of [LegacyNoInterfaceObject] interfaces is supported, // check that it's not specified together with LegacyWindowAlias. // TODO: maybe check that [LegacyWindowAlias] is not specified on a partial interface. @@ -1963,7 +1773,7 @@ IdlInterface.prototype.test_self = function() // Next, test that the [[Prototype]] of the interface prototype object // is correct. (This is made somewhat difficult by the existence of - // [NoInterfaceObject].) + // [LegacyNoInterfaceObject].) // TODO: Aryeh thinks there's at least other place in this file where // we try to figure out if an interface prototype object is // correct. Consolidate that code. @@ -1996,7 +1806,7 @@ IdlInterface.prototype.test_self = function() if (this.base) { inherit_interface = this.base; var parent = this.array.members[inherit_interface]; - if (!parent.has_extended_attribute("NoInterfaceObject")) { + if (!parent.has_extended_attribute("LegacyNoInterfaceObject")) { parent.assert_interface_object_exists(); inherit_interface_interface_object = parent.get_interface_object(); } @@ -2072,8 +1882,8 @@ IdlInterface.prototype.test_self = function() assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); - // "If the [NoInterfaceObject] extended attribute was not specified on - // the interface, then the interface prototype object must also have a + // "If the [LegacyNoInterfaceObject] extended attribute was not specified + // on the interface, then the interface prototype object must also have a // property named “constructor” with attributes { [[Writable]]: true, // [[Enumerable]]: false, [[Configurable]]: true } whose value is a // reference to the interface object for the interface." @@ -2818,9 +2628,6 @@ IdlInterface.prototype.test_object = function(desc) { // Result of [[IsHTMLDDA]] slot expected_typeof = "undefined"; - } else if (this.members.some(function(member) { return member.legacycaller; })) - { - expected_typeof = "function"; } else { @@ -3083,11 +2890,6 @@ IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_ var pendingPromises = []; - // "For each exposed attribute of the interface, whether it was declared on - // the interface itself or one of its consequential interfaces, there MUST - // exist a corresponding property. The characteristics of this property are - // as follows:" - // "The name of the property is the identifier of the attribute." assert_own_property(obj, member.name); diff --git a/test/fixtures/wpt/resources/testdriver.js b/test/fixtures/wpt/resources/testdriver.js index f3cee9821e13f9..f2df26cda1ccdf 100644 --- a/test/fixtures/wpt/resources/testdriver.js +++ b/test/fixtures/wpt/resources/testdriver.js @@ -277,7 +277,7 @@ * @returns {Promise} fulfilled after the permission is set, or rejected if setting the * permission fails */ - set_permission: function(descriptor, state, one_realm, context=null) { + set_permission: function(descriptor, state, one_realm=false, context=null) { let permission_params = { descriptor, state, diff --git a/test/fixtures/wpt/resources/testharness.js b/test/fixtures/wpt/resources/testharness.js index 21fa7933ed2b5a..f85b19fd9bd90c 100644 --- a/test/fixtures/wpt/resources/testharness.js +++ b/test/fixtures/wpt/resources/testharness.js @@ -1,14 +1,5 @@ /*global self*/ /*jshint latedef: nofunc*/ -/* -Distributed under both the W3C Test Suite License [1] and the W3C -3-clause BSD License [2]. To contribute to a W3C Test Suite, see the -policies and contribution forms [3]. - -[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license -[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license -[3] http://www.w3.org/2004/10/27-testcases -*/ /* Documentation: https://web-platform-tests.org/writing-tests/testharness-api.html * (../docs/_writing-tests/testharness-api.md) */ @@ -1190,9 +1181,9 @@ policies and contribution forms [3]. console.debug("ASSERT", name, tests.current_test && tests.current_test.name, args); } if (tests.output) { - tests.set_assert(name, ...args); + tests.set_assert(name, args); } - const rv = f(...args); + const rv = f.apply(undefined, args); status = Test.statuses.PASS; return rv; } catch(e) { @@ -1566,7 +1557,8 @@ policies and contribution forms [3]. function _assert_inherits(name) { return function (object, property_name, description) { - assert(typeof object === "object" || typeof object === "function" || + assert((typeof object === "object" && object !== null) || + typeof object === "function" || // Or has [[IsHTMLDDA]] slot String(object) === "[object HTMLAllCollection]", name, description, @@ -2725,7 +2717,7 @@ policies and contribution forms [3]. return this.formats[this.status]; } - function AssertRecord(test, assert_name, ...args) { + function AssertRecord(test, assert_name, args = []) { this.assert_name = assert_name; this.test = test; // Avoid keeping complex objects alive @@ -3032,8 +3024,8 @@ policies and contribution forms [3]. all_complete); }; - Tests.prototype.set_assert = function(assert_name, ...args) { - this.asserts_run.push(new AssertRecord(this.current_test, assert_name, ...args)) + Tests.prototype.set_assert = function(assert_name, args) { + this.asserts_run.push(new AssertRecord(this.current_test, assert_name, args)) } Tests.prototype.set_assert_status = function(status, stack) { @@ -3463,13 +3455,13 @@ policies and contribution forms [3]. e.preventDefault(); return; } - var result_class = element.parentNode.getAttribute("class"); + var result_class = element.querySelector("span[class]").getAttribute("class"); var style_element = output_document.querySelector("style#hide-" + result_class); var input_element = element.querySelector("input"); if (!style_element && !input_element.checked) { style_element = output_document.createElementNS(xhtml_ns, "style"); style_element.id = "hide-" + result_class; - style_element.textContent = "table#results > tbody > tr."+result_class+"{display:none}"; + style_element.textContent = "table#results > tbody > tr.overall-"+result_class+"{display:none}"; output_document.body.appendChild(style_element); } else if (style_element && input_element.checked) { style_element.parentNode.removeChild(style_element); @@ -3541,10 +3533,11 @@ policies and contribution forms [3]. if (assert.stack) { output_location = assert.stack.split("\n", 1)[0].replace(/@?\w+:\/\/[^ "\/]+(?::\d+)?/g, " "); } - return "" + + return "" + + "" + Test.prototype.status_formats[assert.status] + "" + - "" + "
" +
                     output_fn +
                     (output_location ? "\n" + escape_html(output_location) : "") +
@@ -3564,7 +3557,10 @@ policies and contribution forms [3].
             "";
         for (var i = 0; i < tests.length; i++) {
             var test = tests[i];
-            html += '' +
+                '' +
                 test.format_status() +
diff --git a/test/fixtures/wpt/resources/webidl2/lib/README.md b/test/fixtures/wpt/resources/webidl2/lib/README.md
index 1bd583269d2929..af0af3a902f2f3 100644
--- a/test/fixtures/wpt/resources/webidl2/lib/README.md
+++ b/test/fixtures/wpt/resources/webidl2/lib/README.md
@@ -1,4 +1,6 @@
 This directory contains a built version of the [webidl2.js library](https://github.com/w3c/webidl2.js).
 It is built by running `npm run build-debug` at the root of that repository.
 
+Currently using webidl2.js@24.1.1 (372ea83eaa10f60adff49bd0f4f3ce6a11d6fbec).
+
 The `webidl2.js.headers` file is a local addition to ensure the script is interpreted as UTF-8.
diff --git a/test/fixtures/wpt/resources/webidl2/lib/webidl2.js b/test/fixtures/wpt/resources/webidl2/lib/webidl2.js
index d707905fa63e16..322f0e11a6ae56 100644
--- a/test/fixtures/wpt/resources/webidl2/lib/webidl2.js
+++ b/test/fixtures/wpt/resources/webidl2/lib/webidl2.js
@@ -7,124 +7,18 @@
 		exports["WebIDL2"] = factory();
 	else
 		root["WebIDL2"] = factory();
-})(this, function() {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-/******/
-/******/ 	// The require function
-/******/ 	function __webpack_require__(moduleId) {
-/******/
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId]) {
-/******/ 			return installedModules[moduleId].exports;
-/******/ 		}
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			i: moduleId,
-/******/ 			l: false,
-/******/ 			exports: {}
-/******/ 		};
-/******/
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ 		// Flag the module as loaded
-/******/ 		module.l = true;
-/******/
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-/******/
-/******/
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__webpack_require__.m = modules;
-/******/
-/******/ 	// expose the module cache
-/******/ 	__webpack_require__.c = installedModules;
-/******/
-/******/ 	// define getter function for harmony exports
-/******/ 	__webpack_require__.d = function(exports, name, getter) {
-/******/ 		if(!__webpack_require__.o(exports, name)) {
-/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
-/******/ 		}
-/******/ 	};
-/******/
-/******/ 	// define __esModule on exports
-/******/ 	__webpack_require__.r = function(exports) {
-/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ 		}
-/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
-/******/ 	};
-/******/
-/******/ 	// create a fake namespace object
-/******/ 	// mode & 1: value is a module id, require it
-/******/ 	// mode & 2: merge all properties of value into the ns
-/******/ 	// mode & 4: return value when already ns object
-/******/ 	// mode & 8|1: behave like require
-/******/ 	__webpack_require__.t = function(value, mode) {
-/******/ 		if(mode & 1) value = __webpack_require__(value);
-/******/ 		if(mode & 8) return value;
-/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-/******/ 		var ns = Object.create(null);
-/******/ 		__webpack_require__.r(ns);
-/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-/******/ 		return ns;
-/******/ 	};
-/******/
-/******/ 	// getDefaultExport function for compatibility with non-harmony modules
-/******/ 	__webpack_require__.n = function(module) {
-/******/ 		var getter = module && module.__esModule ?
-/******/ 			function getDefault() { return module['default']; } :
-/******/ 			function getModuleExports() { return module; };
-/******/ 		__webpack_require__.d(getter, 'a', getter);
-/******/ 		return getter;
-/******/ 	};
-/******/
-/******/ 	// Object.prototype.hasOwnProperty.call
-/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ 	// __webpack_public_path__
-/******/ 	__webpack_require__.p = "";
-/******/
-/******/
-/******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony import */ var _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__["parse"]; });
-
-/* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "write", function() { return _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__["write"]; });
-
-/* harmony import */ var _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31);
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "validate", function() { return _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__["validate"]; });
-
-/* harmony import */ var _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebIDLParseError", function() { return _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__["WebIDLParseError"]; });
-
-
-
-
-
-
-
-/***/ }),
+})(globalThis, function() {
+return /******/ (() => { // webpackBootstrap
+/******/ 	"use strict";
+/******/ 	var __webpack_modules__ = ([
+/* 0 */,
 /* 1 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "parse": () => (/* binding */ parse)
+/* harmony export */ });
 /* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15);
 /* harmony import */ var _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16);
@@ -150,8 +44,6 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-
-
 /**
  * @param {Tokeniser} tokeniser
  * @param {object} options
@@ -172,16 +64,17 @@ function parseByTokens(tokeniser, options) {
     const callback = consume("callback");
     if (!callback) return;
     if (tokeniser.probe("interface")) {
-      return _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__["CallbackInterface"].parse(tokeniser, callback);
+      return _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__.CallbackInterface.parse(tokeniser, callback);
     }
-    return _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__["CallbackFunction"].parse(tokeniser, callback);
+    return _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__.CallbackFunction.parse(tokeniser, callback);
   }
 
   function interface_(opts) {
     const base = consume("interface");
     if (!base) return;
-    const ret = _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__["Mixin"].parse(tokeniser, base, opts) ||
-      _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__["Interface"].parse(tokeniser, base, opts) ||
+    const ret =
+      _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__.Mixin.parse(tokeniser, base, opts) ||
+      _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__.Interface.parse(tokeniser, base, opts) ||
       error("Interface has no proper body");
     return ret;
   }
@@ -189,37 +82,41 @@ function parseByTokens(tokeniser, options) {
   function partial() {
     const partial = consume("partial");
     if (!partial) return;
-    return _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__["Dictionary"].parse(tokeniser, { partial }) ||
+    return (
+      _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser, { partial }) ||
       interface_({ partial }) ||
-      _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__["Namespace"].parse(tokeniser, { partial }) ||
-      error("Partial doesn't apply to anything");
+      _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser, { partial }) ||
+      error("Partial doesn't apply to anything")
+    );
   }
 
   function definition() {
-    return callback() ||
+    return (
+      callback() ||
       interface_() ||
       partial() ||
-      _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__["Dictionary"].parse(tokeniser) ||
-      _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__["Enum"].parse(tokeniser) ||
-      _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__["Typedef"].parse(tokeniser) ||
-      _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__["Includes"].parse(tokeniser) ||
-      _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__["Namespace"].parse(tokeniser);
+      _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser) ||
+      _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__.Enum.parse(tokeniser) ||
+      _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__.Typedef.parse(tokeniser) ||
+      _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__.Includes.parse(tokeniser) ||
+      _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser)
+    );
   }
 
   function definitions() {
     if (!source.length) return [];
     const defs = [];
     while (true) {
-      const ea = _productions_extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__["ExtendedAttributes"].parse(tokeniser);
+      const ea = _productions_extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__.ExtendedAttributes.parse(tokeniser);
       const def = definition();
       if (!def) {
         if (ea.length) error("Stray extended attributes");
         break;
       }
-      Object(_productions_helpers_js__WEBPACK_IMPORTED_MODULE_11__["autoParenter"])(def).extAttrs = ea;
+      (0,_productions_helpers_js__WEBPACK_IMPORTED_MODULE_11__.autoParenter)(def).extAttrs = ea;
       defs.push(def);
     }
-    const eof = consume("eof");
+    const eof = tokeniser.consumeType("eof");
     if (options.concrete) {
       defs.push(eof);
     }
@@ -237,7 +134,7 @@ function parseByTokens(tokeniser, options) {
  * @param {boolean} [options.concrete]
  */
 function parse(str, options = {}) {
-  const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__["Tokeniser"](str);
+  const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__.Tokeniser(str);
   if (typeof options.sourceName !== "undefined") {
     tokeniser.source.name = options.sourceName;
   }
@@ -247,15 +144,16 @@ function parse(str, options = {}) {
 
 /***/ }),
 /* 2 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "typeNameKeywords", function() { return typeNameKeywords; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringTypes", function() { return stringTypes; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "argumentNameKeywords", function() { return argumentNameKeywords; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tokeniser", function() { return Tokeniser; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebIDLParseError", function() { return WebIDLParseError; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "typeNameKeywords": () => (/* binding */ typeNameKeywords),
+/* harmony export */   "stringTypes": () => (/* binding */ stringTypes),
+/* harmony export */   "argumentNameKeywords": () => (/* binding */ argumentNameKeywords),
+/* harmony export */   "Tokeniser": () => (/* binding */ Tokeniser),
+/* harmony export */   "WebIDLParseError": () => (/* binding */ WebIDLParseError)
+/* harmony export */ });
 /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
 /* harmony import */ var _productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
@@ -266,13 +164,14 @@ __webpack_require__.r(__webpack_exports__);
 const tokenRe = {
   // This expression uses a lookahead assertion to catch false matches
   // against integers early.
-  "decimal": /-?(?=[0-9]*\.|[0-9]+[eE])(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/y,
-  "integer": /-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/y,
-  "identifier": /[_-]?[A-Za-z][0-9A-Z_a-z-]*/y,
-  "string": /"[^"]*"/y,
-  "whitespace": /[\t\n\r ]+/y,
-  "comment": /((\/(\/.*|\*([^*]|\*[^/])*\*\/)[\t\n\r ]*)+)/y,
-  "other": /[^\t\n\r 0-9A-Za-z]/y
+  decimal:
+    /-?(?=[0-9]*\.|[0-9]+[eE])(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/y,
+  integer: /-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/y,
+  identifier: /[_-]?[A-Za-z][0-9A-Z_a-z-]*/y,
+  string: /"[^"]*"/y,
+  whitespace: /[\t\n\r ]+/y,
+  comment: /\/\/.*|\/\*(.|\n)*?\*\//y,
+  other: /[^\t\n\r 0-9A-Za-z]/y,
 };
 
 const typeNameKeywords = [
@@ -289,14 +188,10 @@ const typeNameKeywords = [
   "Float64Array",
   "any",
   "object",
-  "symbol"
+  "symbol",
 ];
 
-const stringTypes = [
-  "ByteString",
-  "DOMString",
-  "USVString"
-];
+const stringTypes = ["ByteString", "DOMString", "USVString"];
 
 const argumentNameKeywords = [
   "async",
@@ -321,7 +216,7 @@ const argumentNameKeywords = [
   "static",
   "stringifier",
   "typedef",
-  "unrestricted"
+  "unrestricted",
 ];
 
 const nonRegexTerminals = [
@@ -329,7 +224,9 @@ const nonRegexTerminals = [
   "FrozenArray",
   "Infinity",
   "NaN",
+  "ObservableArray",
   "Promise",
+  "bigint",
   "boolean",
   "byte",
   "double",
@@ -346,8 +243,9 @@ const nonRegexTerminals = [
   "sequence",
   "short",
   "true",
+  "undefined",
   "unsigned",
-  "void"
+  "void",
 ].concat(argumentNameKeywords, stringTypes, typeNameKeywords);
 
 const punctuations = [
@@ -364,7 +262,7 @@ const punctuations = [
   "[",
   "]",
   "{",
-  "}"
+  "}",
 ];
 
 const reserved = [
@@ -390,7 +288,7 @@ function tokenise(str) {
 
     if (/[\t\n\r ]/.test(nextChar)) {
       result = attemptTokenMatch("whitespace", { noFlushTrivia: true });
-    } else if (nextChar === '/') {
+    } else if (nextChar === "/") {
       result = attemptTokenMatch("comment", { noFlushTrivia: true });
     }
 
@@ -410,10 +308,14 @@ function tokenise(str) {
         const token = tokens[lastIndex];
         if (result !== -1) {
           if (reserved.includes(token.value)) {
-            const message = `${Object(_productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(token.value)} is a reserved identifier and must not be used.`;
-            throw new WebIDLParseError(Object(_error_js__WEBPACK_IMPORTED_MODULE_0__["syntaxError"])(tokens, lastIndex, null, message));
+            const message = `${(0,_productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(
+              token.value
+            )} is a reserved identifier and must not be used.`;
+            throw new WebIDLParseError(
+              (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(tokens, lastIndex, null, message)
+            );
           } else if (nonRegexTerminals.includes(token.value)) {
-            token.type = token.value;
+            token.type = "inline";
           }
         }
       }
@@ -423,7 +325,13 @@ function tokenise(str) {
 
     for (const punctuation of punctuations) {
       if (str.startsWith(punctuation, lastCharIndex)) {
-        tokens.push({ type: punctuation, value: punctuation, trivia, line, index });
+        tokens.push({
+          type: "inline",
+          value: punctuation,
+          trivia,
+          line,
+          index,
+        });
         trivia = "";
         lastCharIndex += punctuation.length;
         result = lastCharIndex;
@@ -446,7 +354,7 @@ function tokenise(str) {
   tokens.push({
     type: "eof",
     value: "",
-    trivia
+    trivia,
   });
 
   return tokens;
@@ -485,28 +393,55 @@ class Tokeniser {
    * @return {never}
    */
   error(message) {
-    throw new WebIDLParseError(Object(_error_js__WEBPACK_IMPORTED_MODULE_0__["syntaxError"])(this.source, this.position, this.current, message));
+    throw new WebIDLParseError(
+      (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(this.source, this.position, this.current, message)
+    );
   }
 
   /**
    * @param {string} type
    */
-  probe(type) {
-    return this.source.length > this.position && this.source[this.position].type === type;
+  probeType(type) {
+    return (
+      this.source.length > this.position &&
+      this.source[this.position].type === type
+    );
+  }
+
+  /**
+   * @param {string} value
+   */
+  probe(value) {
+    return (
+      this.probeType("inline") && this.source[this.position].value === value
+    );
   }
 
   /**
    * @param  {...string} candidates
    */
-  consume(...candidates) {
+  consumeType(...candidates) {
     for (const type of candidates) {
-      if (!this.probe(type)) continue;
+      if (!this.probeType(type)) continue;
       const token = this.source[this.position];
       this.position++;
       return token;
     }
   }
 
+  /**
+   * @param  {...string} candidates
+   */
+  consume(...candidates) {
+    if (!this.probeType("inline")) return;
+    const token = this.source[this.position];
+    for (const value of candidates) {
+      if (token.value !== value) continue;
+      this.position++;
+      return token;
+    }
+  }
+
   /**
    * @param {number} position
    */
@@ -526,7 +461,15 @@ class WebIDLParseError extends Error {
    * @param {string} options.input
    * @param {*[]} options.tokens
    */
-  constructor({ message, bareMessage, context, line, sourceName, input, tokens }) {
+  constructor({
+    message,
+    bareMessage,
+    context,
+    line,
+    sourceName,
+    input,
+    tokens,
+  }) {
     super(message);
 
     this.name = "WebIDLParseError"; // not to be mangled
@@ -542,12 +485,13 @@ class WebIDLParseError extends Error {
 
 /***/ }),
 /* 3 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "syntaxError", function() { return syntaxError; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validationError", function() { return validationError; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "syntaxError": () => (/* binding */ syntaxError),
+/* harmony export */   "validationError": () => (/* binding */ validationError)
+/* harmony export */ });
 /**
  * @param {string} text
  */
@@ -556,6 +500,24 @@ function lastLine(text) {
   return splitted[splitted.length - 1];
 }
 
+function appendIfExist(base, target) {
+  let result = base;
+  if (target) {
+    result += ` ${target}`;
+  }
+  return result;
+}
+
+function contextAsText(node) {
+  const hierarchy = [node];
+  while (node && node.parent) {
+    const { parent } = node;
+    hierarchy.unshift(parent);
+    node = parent;
+  }
+  return hierarchy.map((n) => appendIfExist(n.type, n.name)).join(" -> ");
+}
+
 /**
  * @typedef {object} WebIDL2ErrorOptions
  * @property {"error" | "warning"} [level]
@@ -565,18 +527,25 @@ function lastLine(text) {
  * @param {"Syntax" | "Validation"} kind error type
  * @param {WebIDL2ErrorOptions} [options]
  */
-function error(source, position, current, message, kind, { level = "error", autofix, ruleName } = {}) {
+function error(
+  source,
+  position,
+  current,
+  message,
+  kind,
+  { level = "error", autofix, ruleName } = {}
+) {
   /**
    * @param {number} count
    */
   function sliceTokens(count) {
-    return count > 0 ?
-      source.slice(position, position + count) :
-      source.slice(Math.max(position + count, 0), position);
+    return count > 0
+      ? source.slice(position, position + count)
+      : source.slice(Math.max(position + count, 0), position);
   }
 
   function tokensToText(inputs, { precedes } = {}) {
-    const text = inputs.map(t => t.trivia + t.value).join("");
+    const text = inputs.map((t) => t.trivia + t.value).join("");
     const nextToken = source[position];
     if (nextToken.type === "eof") {
       return text;
@@ -589,9 +558,11 @@ function error(source, position, current, message, kind, { level = "error", auto
 
   const maxTokens = 5; // arbitrary but works well enough
   const line =
-    source[position].type !== "eof" ? source[position].line :
-    source.length > 1 ? source[position - 1].line :
-    1;
+    source[position].type !== "eof"
+      ? source[position].line
+      : source.length > 1
+      ? source[position - 1].line
+      : 1;
 
   const precedingLastLine = lastLine(
     tokensToText(sliceTokens(-maxTokens), { precedes: true })
@@ -606,7 +577,12 @@ function error(source, position, current, message, kind, { level = "error", auto
 
   const contextType = kind === "Syntax" ? "since" : "inside";
   const inSourceName = source.name ? ` in ${source.name}` : "";
-  const grammaticalContext = (current && current.name) ? `, ${contextType} \`${current.partial ? "partial " : ""}${current.type} ${current.name}\`` : "";
+  const grammaticalContext =
+    current && current.name
+      ? `, ${contextType} \`${current.partial ? "partial " : ""}${contextAsText(
+          current
+        )}\``
+      : "";
   const context = `${kind} error at line ${line}${inSourceName}${grammaticalContext}:\n${sourceContext}`;
   return {
     message: `${context} ${message}`,
@@ -618,7 +594,7 @@ function error(source, position, current, message, kind, { level = "error", auto
     ruleName,
     autofix,
     input: subsequentText,
-    tokens: subsequentTokens
+    tokens: subsequentTokens,
   };
 }
 
@@ -633,33 +609,47 @@ function syntaxError(source, position, current, message) {
  * @param {string} message error message
  * @param {WebIDL2ErrorOptions} [options]
  */
-function validationError(token, current, ruleName, message, options = {}) {
+function validationError(
+  token,
+  current,
+  ruleName,
+  message,
+  options = {}
+) {
   options.ruleName = ruleName;
-  return error(current.source, token.index, current, message, "Validation", options);
+  return error(
+    current.source,
+    token.index,
+    current,
+    message,
+    "Validation",
+    options
+  );
 }
 
 
 /***/ }),
 /* 4 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unescape", function() { return unescape; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "list", function() { return list; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "const_value", function() { return const_value; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "const_data", function() { return const_data; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "primitive_type", function() { return primitive_type; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "argument_list", function() { return argument_list; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "type_with_extended_attributes", function() { return type_with_extended_attributes; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "return_type", function() { return return_type; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringifier", function() { return stringifier; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getLastIndentation", function() { return getLastIndentation; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMemberIndentation", function() { return getMemberIndentation; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autofixAddExposedWindow", function() { return autofixAddExposedWindow; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getFirstToken", function() { return getFirstToken; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findLastIndex", function() { return findLastIndex; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "autoParenter", function() { return autoParenter; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "unescape": () => (/* binding */ unescape),
+/* harmony export */   "list": () => (/* binding */ list),
+/* harmony export */   "const_value": () => (/* binding */ const_value),
+/* harmony export */   "const_data": () => (/* binding */ const_data),
+/* harmony export */   "primitive_type": () => (/* binding */ primitive_type),
+/* harmony export */   "argument_list": () => (/* binding */ argument_list),
+/* harmony export */   "type_with_extended_attributes": () => (/* binding */ type_with_extended_attributes),
+/* harmony export */   "return_type": () => (/* binding */ return_type),
+/* harmony export */   "stringifier": () => (/* binding */ stringifier),
+/* harmony export */   "getLastIndentation": () => (/* binding */ getLastIndentation),
+/* harmony export */   "getMemberIndentation": () => (/* binding */ getMemberIndentation),
+/* harmony export */   "autofixAddExposedWindow": () => (/* binding */ autofixAddExposedWindow),
+/* harmony export */   "getFirstToken": () => (/* binding */ getFirstToken),
+/* harmony export */   "findLastIndex": () => (/* binding */ findLastIndex),
+/* harmony export */   "autoParenter": () => (/* binding */ autoParenter)
+/* harmony export */ });
 /* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5);
 /* harmony import */ var _argument_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
 /* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8);
@@ -677,7 +667,7 @@ __webpack_require__.r(__webpack_exports__);
  * @param {string} identifier
  */
 function unescape(identifier) {
-  return identifier.startsWith('_') ? identifier.slice(1) : identifier;
+  return identifier.startsWith("_") ? identifier.slice(1) : identifier;
 }
 
 /**
@@ -714,7 +704,10 @@ function list(tokeniser, { parser, allowDangler, listName = "list" }) {
  * @param {import("../tokeniser").Tokeniser} tokeniser
  */
 function const_value(tokeniser) {
-  return tokeniser.consume("true", "false", "Infinity", "-Infinity", "NaN", "decimal", "integer");
+  return (
+    tokeniser.consumeType("decimal", "integer") ||
+    tokeniser.consume("true", "false", "Infinity", "-Infinity", "NaN")
+  );
 }
 
 /**
@@ -724,23 +717,26 @@ function const_value(tokeniser) {
  */
 function const_data({ type, value }) {
   switch (type) {
+    case "decimal":
+    case "integer":
+      return { type: "number", value };
+    case "string":
+      return { type: "string", value: value.slice(1, -1) };
+  }
+
+  switch (value) {
     case "true":
     case "false":
-      return { type: "boolean", value: type === "true" };
+      return { type: "boolean", value: value === "true" };
     case "Infinity":
     case "-Infinity":
-      return { type: "Infinity", negative: type.startsWith("-") };
+      return { type: "Infinity", negative: value.startsWith("-") };
     case "[":
       return { type: "sequence", value: [] };
     case "{":
       return { type: "dictionary" };
-    case "decimal":
-    case "integer":
-      return { type: "number", value };
-    case "string":
-      return { type: "string", value: value.slice(1, -1) };
     default:
-      return { type };
+      return { type: value };
   }
 }
 
@@ -753,7 +749,7 @@ function primitive_type(tokeniser) {
     const base = tokeniser.consume("short", "long");
     if (base) {
       const postfix = tokeniser.consume("long");
-      return new _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"]({ source, tokens: { prefix, base, postfix } });
+      return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { prefix, base, postfix } });
     }
     if (prefix) tokeniser.error("Failed to parse integer type");
   }
@@ -762,7 +758,7 @@ function primitive_type(tokeniser) {
     const prefix = tokeniser.consume("unrestricted");
     const base = tokeniser.consume("float", "double");
     if (base) {
-      return new _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"]({ source, tokens: { prefix, base } });
+      return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { prefix, base } });
     }
     if (prefix) tokeniser.error("Failed to parse float type");
   }
@@ -770,9 +766,15 @@ function primitive_type(tokeniser) {
   const { source } = tokeniser;
   const num_type = integer_type(tokeniser) || decimal_type(tokeniser);
   if (num_type) return num_type;
-  const base = tokeniser.consume("boolean", "byte", "octet");
+  const base = tokeniser.consume(
+    "bigint",
+    "boolean",
+    "byte",
+    "octet",
+    "undefined"
+  );
   if (base) {
-    return new _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"]({ source, tokens: { base } });
+    return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { base } });
   }
 }
 
@@ -780,7 +782,10 @@ function primitive_type(tokeniser) {
  * @param {import("../tokeniser").Tokeniser} tokeniser
  */
 function argument_list(tokeniser) {
-  return list(tokeniser, { parser: _argument_js__WEBPACK_IMPORTED_MODULE_1__["Argument"].parse, listName: "arguments list" });
+  return list(tokeniser, {
+    parser: _argument_js__WEBPACK_IMPORTED_MODULE_1__.Argument.parse,
+    listName: "arguments list",
+  });
 }
 
 /**
@@ -788,8 +793,8 @@ function argument_list(tokeniser) {
  * @param {string} typeName
  */
 function type_with_extended_attributes(tokeniser, typeName) {
-  const extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__["ExtendedAttributes"].parse(tokeniser);
-  const ret = _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"].parse(tokeniser, typeName);
+  const extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser);
+  const ret = _type_js__WEBPACK_IMPORTED_MODULE_0__.Type.parse(tokeniser, typeName);
   if (ret) autoParenter(ret).extAttrs = extAttrs;
   return ret;
 }
@@ -799,13 +804,16 @@ function type_with_extended_attributes(tokeniser, typeName) {
  * @param {string} typeName
  */
 function return_type(tokeniser, typeName) {
-  const typ = _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"].parse(tokeniser, typeName || "return-type");
+  const typ = _type_js__WEBPACK_IMPORTED_MODULE_0__.Type.parse(tokeniser, typeName || "return-type");
   if (typ) {
     return typ;
   }
   const voidToken = tokeniser.consume("void");
   if (voidToken) {
-    const ret = new _type_js__WEBPACK_IMPORTED_MODULE_0__["Type"]({ source: tokeniser.source, tokens: { base: voidToken } });
+    const ret = new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({
+      source: tokeniser.source,
+      tokens: { base: voidToken },
+    });
     ret.type = "return-type";
     return ret;
   }
@@ -817,8 +825,9 @@ function return_type(tokeniser, typeName) {
 function stringifier(tokeniser) {
   const special = tokeniser.consume("stringifier");
   if (!special) return;
-  const member = _attribute_js__WEBPACK_IMPORTED_MODULE_4__["Attribute"].parse(tokeniser, { special }) ||
-    _operation_js__WEBPACK_IMPORTED_MODULE_3__["Operation"].parse(tokeniser, { special }) ||
+  const member =
+    _attribute_js__WEBPACK_IMPORTED_MODULE_4__.Attribute.parse(tokeniser, { special }) ||
+    _operation_js__WEBPACK_IMPORTED_MODULE_3__.Operation.parse(tokeniser, { special }) ||
     tokeniser.error("Unterminated stringifier");
   return member;
 }
@@ -853,9 +862,9 @@ function getMemberIndentation(parentTrivia) {
  */
 function autofixAddExposedWindow(def) {
   return () => {
-    if (def.extAttrs.length){
-      const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__["Tokeniser"]("Exposed=Window,");
-      const exposed = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__["SimpleExtendedAttribute"].parse(tokeniser);
+    if (def.extAttrs.length) {
+      const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("Exposed=Window,");
+      const exposed = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.SimpleExtendedAttribute.parse(tokeniser);
       exposed.tokens.separator = tokeniser.consume(",");
       const existing = def.extAttrs[0];
       if (!/^\s/.test(existing.tokens.name.trivia)) {
@@ -863,7 +872,9 @@ function autofixAddExposedWindow(def) {
       }
       def.extAttrs.unshift(exposed);
     } else {
-      autoParenter(def).extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__["ExtendedAttributes"].parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__["Tokeniser"]("[Exposed=Window]"));
+      autoParenter(def).extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(
+        new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("[Exposed=Window]")
+      );
       const trivia = def.tokens.base.trivia;
       def.extAttrs.tokens.open.trivia = trivia;
       def.tokens.base.trivia = `\n${getLastIndentation(trivia)}`;
@@ -942,18 +953,19 @@ function autoParenter(data, parent) {
         value.parent = parent;
       }
       return true;
-    }
+    },
   });
 }
 
 
 /***/ }),
 /* 5 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Type", function() { return Type; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Type": () => (/* binding */ Type)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
@@ -972,38 +984,66 @@ __webpack_require__.r(__webpack_exports__);
  * @param {string} typeName
  */
 function generic_type(tokeniser, typeName) {
-  const base = tokeniser.consume("FrozenArray", "Promise", "sequence", "record");
+  const base = tokeniser.consume(
+    "FrozenArray",
+    "ObservableArray",
+    "Promise",
+    "sequence",
+    "record"
+  );
   if (!base) {
     return;
   }
-  const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Type({ source: tokeniser.source, tokens: { base } }));
-  ret.tokens.open = tokeniser.consume("<") || tokeniser.error(`No opening bracket after ${base.type}`);
-  switch (base.type) {
+  const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(
+    new Type({ source: tokeniser.source, tokens: { base } })
+  );
+  ret.tokens.open =
+    tokeniser.consume("<") ||
+    tokeniser.error(`No opening bracket after ${base.value}`);
+  switch (base.value) {
     case "Promise": {
-      if (tokeniser.probe("[")) tokeniser.error("Promise type cannot have extended attribute");
-      const subtype = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["return_type"])(tokeniser, typeName) || tokeniser.error("Missing Promise subtype");
+      if (tokeniser.probe("["))
+        tokeniser.error("Promise type cannot have extended attribute");
+      const subtype =
+        (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser, typeName) ||
+        tokeniser.error("Missing Promise subtype");
       ret.subtype.push(subtype);
       break;
     }
     case "sequence":
-    case "FrozenArray": {
-      const subtype = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser, typeName) || tokeniser.error(`Missing ${base.type} subtype`);
+    case "FrozenArray":
+    case "ObservableArray": {
+      const subtype =
+        (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, typeName) ||
+        tokeniser.error(`Missing ${base.value} subtype`);
       ret.subtype.push(subtype);
       break;
     }
     case "record": {
-      if (tokeniser.probe("[")) tokeniser.error("Record key cannot have extended attribute");
-      const keyType = tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__["stringTypes"]) || tokeniser.error(`Record key must be one of: ${_tokeniser_js__WEBPACK_IMPORTED_MODULE_2__["stringTypes"].join(", ")}`);
-      const keyIdlType = new Type({ source: tokeniser.source, tokens: { base: keyType }});
-      keyIdlType.tokens.separator = tokeniser.consume(",") || tokeniser.error("Missing comma after record key type");
+      if (tokeniser.probe("["))
+        tokeniser.error("Record key cannot have extended attribute");
+      const keyType =
+        tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes) ||
+        tokeniser.error(`Record key must be one of: ${_tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes.join(", ")}`);
+      const keyIdlType = new Type({
+        source: tokeniser.source,
+        tokens: { base: keyType },
+      });
+      keyIdlType.tokens.separator =
+        tokeniser.consume(",") ||
+        tokeniser.error("Missing comma after record key type");
       keyIdlType.type = typeName;
-      const valueType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser, typeName) || tokeniser.error("Error parsing generic type record");
+      const valueType =
+        (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, typeName) ||
+        tokeniser.error("Error parsing generic type record");
       ret.subtype.push(keyIdlType, valueType);
       break;
     }
   }
-  if (!ret.idlType) tokeniser.error(`Error parsing generic type ${base.type}`);
-  ret.tokens.close = tokeniser.consume(">") || tokeniser.error(`Missing closing bracket after ${base.type}`);
+  if (!ret.idlType) tokeniser.error(`Error parsing generic type ${base.value}`);
+  ret.tokens.close =
+    tokeniser.consume(">") ||
+    tokeniser.error(`Missing closing bracket after ${base.value}`);
   return ret.this;
 }
 
@@ -1023,21 +1063,25 @@ function type_suffix(tokeniser, obj) {
  * @param {string} typeName
  */
 function single_type(tokeniser, typeName) {
-  let ret = generic_type(tokeniser, typeName) || Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["primitive_type"])(tokeniser);
+  let ret = generic_type(tokeniser, typeName) || (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.primitive_type)(tokeniser);
   if (!ret) {
-    const base = tokeniser.consume("identifier", ..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__["stringTypes"], ..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__["typeNameKeywords"]);
+    const base =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes, ..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.typeNameKeywords);
     if (!base) {
       return;
     }
     ret = new Type({ source: tokeniser.source, tokens: { base } });
-    if (tokeniser.probe("<")) tokeniser.error(`Unsupported generic type ${base.value}`);
+    if (tokeniser.probe("<"))
+      tokeniser.error(`Unsupported generic type ${base.value}`);
   }
   if (ret.generic === "Promise" && tokeniser.probe("?")) {
     tokeniser.error("Promise type cannot be nullable");
   }
   ret.type = typeName || null;
   type_suffix(tokeniser, ret);
-  if (ret.nullable && ret.idlType === "any") tokeniser.error("Type `any` cannot be made nullable");
+  if (ret.nullable && ret.idlType === "any")
+    tokeniser.error("Type `any` cannot be made nullable");
   return ret;
 }
 
@@ -1049,28 +1093,34 @@ function union_type(tokeniser, type) {
   const tokens = {};
   tokens.open = tokeniser.consume("(");
   if (!tokens.open) return;
-  const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Type({ source: tokeniser.source, tokens }));
+  const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Type({ source: tokeniser.source, tokens }));
   ret.type = type || null;
   while (true) {
-    const typ = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser) || tokeniser.error("No type after open parenthesis or 'or' in union type");
-    if (typ.idlType === "any") tokeniser.error("Type `any` cannot be included in a union type");
-    if (typ.generic === "Promise") tokeniser.error("Type `Promise` cannot be included in a union type");
+    const typ =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) ||
+      tokeniser.error("No type after open parenthesis or 'or' in union type");
+    if (typ.idlType === "any")
+      tokeniser.error("Type `any` cannot be included in a union type");
+    if (typ.generic === "Promise")
+      tokeniser.error("Type `Promise` cannot be included in a union type");
     ret.subtype.push(typ);
     const or = tokeniser.consume("or");
     if (or) {
       typ.tokens.separator = or;
-    }
-    else break;
+    } else break;
   }
   if (ret.idlType.length < 2) {
-    tokeniser.error("At least two types are expected in a union type but found less");
+    tokeniser.error(
+      "At least two types are expected in a union type but found less"
+    );
   }
-  tokens.close = tokeniser.consume(")") || tokeniser.error("Unterminated union type");
+  tokens.close =
+    tokeniser.consume(")") || tokeniser.error("Unterminated union type");
   type_suffix(tokeniser, ret);
   return ret.this;
 }
 
-class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    * @param {string} typeName
@@ -1082,7 +1132,7 @@ class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
   constructor({ source, tokens }) {
     super({ source, tokens });
     Object.defineProperty(this, "subtype", { value: [], writable: true });
-    this.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_5__["ExtendedAttributes"]({});
+    this.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_5__.ExtendedAttributes({});
   }
 
   get generic() {
@@ -1102,32 +1152,47 @@ class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       return this.subtype;
     }
     // Adding prefixes/postfixes for "unrestricted float", etc.
-    const name = [
-      this.tokens.prefix,
-      this.tokens.base,
-      this.tokens.postfix
-    ].filter(t => t).map(t => t.value).join(" ");
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(name);
+    const name = [this.tokens.prefix, this.tokens.base, this.tokens.postfix]
+      .filter((t) => t)
+      .map((t) => t.value)
+      .join(" ");
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(name);
   }
 
   *validate(defs) {
     yield* this.extAttrs.validate(defs);
+
+    if (this.idlType === "void") {
+      const message = `\`void\` is now replaced by \`undefined\`. Refer to the \
+[relevant GitHub issue](https://github.com/heycam/webidl/issues/60) \
+for more information.`;
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)(this.tokens.base, this, "replace-void", message, {
+        autofix: replaceVoid(this),
+      });
+    }
+
     /*
      * If a union is nullable, its subunions cannot include a dictionary
      * If not, subunions may include dictionaries if each union is not nullable
      */
     const typedef = !this.union && defs.unique.get(this.idlType);
-    const target =
-      this.union ? this :
-      (typedef && typedef.type === "typedef") ? typedef.idlType :
-      undefined;
+    const target = this.union
+      ? this
+      : typedef && typedef.type === "typedef"
+      ? typedef.idlType
+      : undefined;
     if (target && this.nullable) {
       // do not allow any dictionary
-      const { reference } = Object(_validators_helpers_js__WEBPACK_IMPORTED_MODULE_4__["idlTypeIncludesDictionary"])(target, defs) || {};
+      const { reference } = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_4__.idlTypeIncludesDictionary)(target, defs) || {};
       if (reference) {
         const targetToken = (this.union ? reference : this).tokens.base;
-        const message = `Nullable union cannot include a dictionary type`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_3__["validationError"])(targetToken, this, "no-nullable-union-dict", message);
+        const message = "Nullable union cannot include a dictionary type.";
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)(
+          targetToken,
+          this,
+          "no-nullable-union-dict",
+          message
+        );
       }
     } else {
       // allow some dictionary
@@ -1136,16 +1201,59 @@ class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       }
     }
   }
+
+  /** @param {import("../writer.js").Writer)} w */
+  write(w) {
+    const type_body = () => {
+      if (this.union || this.generic) {
+        return w.ts.wrap([
+          w.token(this.tokens.base, w.ts.generic),
+          w.token(this.tokens.open),
+          ...this.subtype.map((t) => t.write(w)),
+          w.token(this.tokens.close),
+        ]);
+      }
+      const firstToken = this.tokens.prefix || this.tokens.base;
+      const prefix = this.tokens.prefix
+        ? [this.tokens.prefix.value, w.ts.trivia(this.tokens.base.trivia)]
+        : [];
+      const ref = w.reference(
+        w.ts.wrap([
+          ...prefix,
+          this.tokens.base.value,
+          w.token(this.tokens.postfix),
+        ]),
+        { unescaped: this.idlType, context: this }
+      );
+      return w.ts.wrap([w.ts.trivia(firstToken.trivia), ref]);
+    };
+    return w.ts.wrap([
+      this.extAttrs.write(w),
+      type_body(),
+      w.token(this.tokens.nullable),
+      w.token(this.tokens.separator),
+    ]);
+  }
+}
+
+/**
+ * @param {Type} type
+ */
+function replaceVoid(type) {
+  return () => {
+    type.tokens.base.value = "undefined";
+  };
 }
 
 
 /***/ }),
 /* 6 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Base", function() { return Base; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Base": () => (/* binding */ Base)
+/* harmony export */ });
 // @ts-check
 
 class Base {
@@ -1159,7 +1267,7 @@ class Base {
       source: { value: source },
       tokens: { value: tokens, writable: true },
       parent: { value: null, writable: true },
-      this: { value: this } // useful when escaping from proxy
+      this: { value: this }, // useful when escaping from proxy
     });
   }
 
@@ -1183,12 +1291,13 @@ class Base {
 
 /***/ }),
 /* 7 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "idlTypeIncludesDictionary", function() { return idlTypeIncludesDictionary; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dictionaryIncludesRequiredField", function() { return dictionaryIncludesRequiredField; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "idlTypeIncludesDictionary": () => (/* binding */ idlTypeIncludesDictionary),
+/* harmony export */   "dictionaryIncludesRequiredField": () => (/* binding */ dictionaryIncludesRequiredField)
+/* harmony export */ });
 // @ts-check
 
 /**
@@ -1200,7 +1309,11 @@ __webpack_require__.r(__webpack_exports__);
  * @param {boolean} [options.useNullableInner] use when the input idlType is nullable and you want to use its inner type
  * @return {{ reference: *, dictionary: Dictionary }} the type reference that ultimately includes dictionary.
  */
-function idlTypeIncludesDictionary(idlType, defs, { useNullableInner } = {}) {
+function idlTypeIncludesDictionary(
+  idlType,
+  defs,
+  { useNullableInner } = {}
+) {
   if (!idlType.union) {
     const def = defs.unique.get(idlType.idlType);
     if (!def) {
@@ -1219,14 +1332,14 @@ function idlTypeIncludesDictionary(idlType, defs, { useNullableInner } = {}) {
       if (result) {
         return {
           reference: idlType,
-          dictionary: result.dictionary
+          dictionary: result.dictionary,
         };
       }
     }
     if (def.type === "dictionary" && (useNullableInner || !idlType.nullable)) {
       return {
         reference: idlType,
-        dictionary: def
+        dictionary: def,
       };
     }
   }
@@ -1238,7 +1351,7 @@ function idlTypeIncludesDictionary(idlType, defs, { useNullableInner } = {}) {
       }
       return {
         reference: subtype,
-        dictionary: result.dictionary
+        dictionary: result.dictionary,
       };
     }
   }
@@ -1253,17 +1366,19 @@ function dictionaryIncludesRequiredField(dict, defs) {
   if (defs.cache.dictionaryIncludesRequiredField.has(dict)) {
     return defs.cache.dictionaryIncludesRequiredField.get(dict);
   }
-  defs.cache.dictionaryIncludesRequiredField.set(dict, undefined); // indeterminate
-  if (dict.inheritance) {
+  // Set cached result to indeterminate to short-circuit circular definitions.
+  // The final result will be updated to true or false.
+  defs.cache.dictionaryIncludesRequiredField.set(dict, undefined);
+  let result = dict.members.some((field) => field.required);
+  if (!result && dict.inheritance) {
     const superdict = defs.unique.get(dict.inheritance);
     if (!superdict) {
-      return true;
-    }
-    if (dictionaryIncludesRequiredField(superdict, defs)) {
-      return true;
+      // Assume required members in the supertype if it is unknown.
+      result = true;
+    } else if (dictionaryIncludesRequiredField(superdict, defs)) {
+      result = true;
     }
   }
-  const result = dict.members.some(field => field.required);
   defs.cache.dictionaryIncludesRequiredField.set(dict, result);
   return result;
 }
@@ -1271,12 +1386,13 @@ function dictionaryIncludesRequiredField(dict, defs) {
 
 /***/ }),
 /* 8 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleExtendedAttribute", function() { return SimpleExtendedAttribute; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExtendedAttributes", function() { return ExtendedAttributes; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "SimpleExtendedAttribute": () => (/* binding */ SimpleExtendedAttribute),
+/* harmony export */   "ExtendedAttributes": () => (/* binding */ ExtendedAttributes)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _array_base_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9);
 /* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
@@ -1293,9 +1409,9 @@ __webpack_require__.r(__webpack_exports__);
  * @param {string} tokenName
  */
 function tokens(tokeniser, tokenName) {
-  return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["list"])(tokeniser, {
-    parser: _token_js__WEBPACK_IMPORTED_MODULE_2__["Token"].parser(tokeniser, tokenName),
-    listName: tokenName + " list"
+  return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.list)(tokeniser, {
+    parser: _token_js__WEBPACK_IMPORTED_MODULE_2__.WrappedToken.parser(tokeniser, tokenName),
+    listName: tokenName + " list",
   });
 }
 
@@ -1310,7 +1426,7 @@ const shouldBeLegacyPrefixed = [
 ];
 
 const renamedLegacies = new Map([
-  ...shouldBeLegacyPrefixed.map(name => [name, `Legacy${name}`]),
+  ...shouldBeLegacyPrefixed.map((name) => [name, `Legacy${name}`]),
   ["NamedConstructor", "LegacyFactoryFunction"],
   ["OverrideBuiltins", "LegacyOverrideBuiltIns"],
   ["TreatNullAs", "LegacyNullToEmptyString"],
@@ -1327,28 +1443,33 @@ function extAttrListItems(tokeniser) {
       return toks;
     }
   }
-  tokeniser.error(`Expected identifiers, strings, decimals, or integers but none found`);
+  tokeniser.error(
+    `Expected identifiers, strings, decimals, or integers but none found`
+  );
 }
 
-
-class ExtendedAttributeParameters extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class ExtendedAttributeParameters extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
     const tokens = { assign: tokeniser.consume("=") };
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["autoParenter"])(new ExtendedAttributeParameters({ source: tokeniser.source, tokens }));
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)(
+      new ExtendedAttributeParameters({ source: tokeniser.source, tokens })
+    );
     if (tokens.assign) {
-      tokens.secondaryName = tokeniser.consume(...extAttrValueSyntax);
+      tokens.secondaryName = tokeniser.consumeType(...extAttrValueSyntax);
     }
     tokens.open = tokeniser.consume("(");
     if (tokens.open) {
-      ret.list = ret.rhsIsList ?
-        // [Exposed=(Window,Worker)]
-        extAttrListItems(tokeniser) :
-        // [LegacyFactoryFunction=Audio(DOMString src)] or [Constructor(DOMString str)]
-        Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["argument_list"])(tokeniser);
-      tokens.close = tokeniser.consume(")") || tokeniser.error("Unexpected token in extended attribute argument list");
+      ret.list = ret.rhsIsList
+        ? // [Exposed=(Window,Worker)]
+          extAttrListItems(tokeniser)
+        : // [LegacyFactoryFunction=Audio(DOMString src)] or [Constructor(DOMString str)]
+          (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.argument_list)(tokeniser);
+      tokens.close =
+        tokeniser.consume(")") ||
+        tokeniser.error("Unexpected token in extended attribute argument list");
     } else if (ret.hasRhs && !tokens.secondaryName) {
       tokeniser.error("No right hand side to extended attribute assignment");
     }
@@ -1368,19 +1489,45 @@ class ExtendedAttributeParameters extends _base_js__WEBPACK_IMPORTED_MODULE_0__[
     }
     return null;
   }
+
+  /** @param {import("../writer.js").Writer)} w */
+  write(w) {
+    function extended_attribute_listitem(item) {
+      return w.ts.wrap([
+        w.token(item.tokens.value),
+        w.token(item.tokens.separator),
+      ]);
+    }
+    const { rhsType } = this;
+    return w.ts.wrap([
+      w.token(this.tokens.assign),
+      w.reference_token(this.tokens.secondaryName, this.parent),
+      w.token(this.tokens.open),
+      ...(!this.list
+        ? []
+        : this.list.map((p) => {
+            return rhsType === "identifier-list"
+              ? w.identifier(p, this.parent)
+              : rhsType && rhsType.endsWith("-list")
+              ? extended_attribute_listitem(p)
+              : p.write(w);
+          })),
+      w.token(this.tokens.close),
+    ]);
+  }
 }
 
-class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
-    const name = tokeniser.consume("identifier");
+    const name = tokeniser.consumeType("identifier");
     if (name) {
       return new SimpleExtendedAttribute({
         source: tokeniser.source,
         tokens: { name },
-        params: ExtendedAttributeParameters.parse(tokeniser)
+        params: ExtendedAttributeParameters.parse(tokeniser),
       });
     }
   }
@@ -1402,7 +1549,9 @@ class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Bas
     if (!type) {
       return null;
     }
-    const value = this.params.rhsIsList ? list : Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["unescape"])(tokens.secondaryName.value);
+    const value = this.params.rhsIsList
+      ? list
+      : (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(tokens.secondaryName.value);
     return { type, value };
   }
   get arguments() {
@@ -1420,21 +1569,41 @@ class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Bas
 undesirable feature that may be removed from Web IDL in the future. Refer to the \
 [relevant upstream PR](https://github.com/heycam/webidl/pull/609) for more \
 information.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_4__["validationError"])(this.tokens.name, this, "no-nointerfaceobject", message, { level: "warning" });
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_4__.validationError)(
+        this.tokens.name,
+        this,
+        "no-nointerfaceobject",
+        message,
+        { level: "warning" }
+      );
     } else if (renamedLegacies.has(name)) {
       const message = `\`[${name}]\` extended attribute is a legacy feature \
 that is now renamed to \`[${renamedLegacies.get(name)}]\`. Refer to the \
 [relevant upstream PR](https://github.com/heycam/webidl/pull/870) for more \
 information.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_4__["validationError"])(this.tokens.name, this, "renamed-legacy", message, {
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_4__.validationError)(this.tokens.name, this, "renamed-legacy", message, {
         level: "warning",
-        autofix: renameLegacyExtendedAttribute(this)
+        autofix: renameLegacyExtendedAttribute(this),
       });
     }
     for (const arg of this.arguments) {
       yield* arg.validate(defs);
     }
   }
+
+  /** @param {import("../writer.js").Writer)} w */
+  write(w) {
+    return w.ts.wrap([
+      w.ts.trivia(this.tokens.name.trivia),
+      w.ts.extendedAttribute(
+        w.ts.wrap([
+          w.ts.extendedAttributeReference(this.name),
+          this.params.write(w),
+        ])
+      ),
+      w.token(this.tokens.separator),
+    ]);
+  }
 }
 
 /**
@@ -1452,7 +1621,7 @@ function renameLegacyExtendedAttribute(extAttr) {
 
 // Note: we parse something simpler than the official syntax. It's all that ever
 // seems to be used
-class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__["ArrayBase"] {
+class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__.ArrayBase {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -1461,16 +1630,22 @@ class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__["Ar
     tokens.open = tokeniser.consume("[");
     if (!tokens.open) return new ExtendedAttributes({});
     const ret = new ExtendedAttributes({ source: tokeniser.source, tokens });
-    ret.push(...Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["list"])(tokeniser, {
-      parser: SimpleExtendedAttribute.parse,
-      listName: "extended attribute"
-    }));
-    tokens.close = tokeniser.consume("]") || tokeniser.error("Unexpected closing token of extended attribute");
+    ret.push(
+      ...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.list)(tokeniser, {
+        parser: SimpleExtendedAttribute.parse,
+        listName: "extended attribute",
+      })
+    );
+    tokens.close =
+      tokeniser.consume("]") ||
+      tokeniser.error("Unexpected closing token of extended attribute");
     if (!ret.length) {
       tokeniser.error("Found an empty extended attribute");
     }
     if (tokeniser.probe("[")) {
-      tokeniser.error("Illegal double extended attribute lists, consider merging them");
+      tokeniser.error(
+        "Illegal double extended attribute lists, consider merging them"
+      );
     }
     return ret;
   }
@@ -1480,16 +1655,27 @@ class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__["Ar
       yield* extAttr.validate(defs);
     }
   }
+
+  /** @param {import("../writer.js").Writer)} w */
+  write(w) {
+    if (!this.length) return "";
+    return w.ts.wrap([
+      w.token(this.tokens.open),
+      ...this.map((ea) => ea.write(w)),
+      w.token(this.tokens.close),
+    ]);
+  }
 }
 
 
 /***/ }),
 /* 9 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArrayBase", function() { return ArrayBase; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "ArrayBase": () => (/* binding */ ArrayBase)
+/* harmony export */ });
 // @ts-check
 
 class ArrayBase extends Array {
@@ -1498,7 +1684,7 @@ class ArrayBase extends Array {
     Object.defineProperties(this, {
       source: { value: source },
       tokens: { value: tokens },
-      parent: { value: null, writable: true }
+      parent: { value: null, writable: true },
     });
   }
 }
@@ -1506,11 +1692,12 @@ class ArrayBase extends Array {
 
 /***/ }),
 /* 10 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Token", function() { return Token; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "WrappedToken": () => (/* binding */ WrappedToken)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 // @ts-check
@@ -1518,33 +1705,37 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Token extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class WrappedToken extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    * @param {string} type
    */
   static parser(tokeniser, type) {
     return () => {
-      const value = tokeniser.consume(type);
+      const value = tokeniser.consumeType(type);
       if (value) {
-        return new Token({ source: tokeniser.source, tokens: { value } });
+        return new WrappedToken({
+          source: tokeniser.source,
+          tokens: { value },
+        });
       }
     };
   }
 
   get value() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.value.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.value.value);
   }
 }
 
 
 /***/ }),
 /* 11 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Argument", function() { return Argument; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Argument": () => (/* binding */ Argument)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _default_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12);
 /* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8);
@@ -1562,7 +1753,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -1570,21 +1761,25 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     const start_position = tokeniser.position;
     /** @type {Base["tokens"]} */
     const tokens = {};
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["autoParenter"])(new Argument({ source: tokeniser.source, tokens }));
-    ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__["ExtendedAttributes"].parse(tokeniser);
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)(
+      new Argument({ source: tokeniser.source, tokens })
+    );
+    ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser);
     tokens.optional = tokeniser.consume("optional");
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["type_with_extended_attributes"])(tokeniser, "argument-type");
+    ret.idlType = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.type_with_extended_attributes)(tokeniser, "argument-type");
     if (!ret.idlType) {
       return tokeniser.unconsume(start_position);
     }
     if (!tokens.optional) {
       tokens.variadic = tokeniser.consume("...");
     }
-    tokens.name = tokeniser.consume("identifier", ..._tokeniser_js__WEBPACK_IMPORTED_MODULE_4__["argumentNameKeywords"]);
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_4__.argumentNameKeywords);
     if (!tokens.name) {
       return tokeniser.unconsume(start_position);
     }
-    ret.default = tokens.optional ? _default_js__WEBPACK_IMPORTED_MODULE_1__["Default"].parse(tokeniser) : null;
+    ret.default = tokens.optional ? _default_js__WEBPACK_IMPORTED_MODULE_1__.Default.parse(tokeniser) : null;
     return ret.this;
   }
 
@@ -1598,34 +1793,71 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return !!this.tokens.variadic;
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(this.tokens.name.value);
   }
 
   /**
    * @param {import("../validator.js").Definitions} defs
    */
   *validate(defs) {
+    yield* this.extAttrs.validate(defs);
     yield* this.idlType.validate(defs);
-    const result = Object(_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__["idlTypeIncludesDictionary"])(this.idlType, defs, { useNullableInner: true });
+    const result = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__.idlTypeIncludesDictionary)(this.idlType, defs, {
+      useNullableInner: true,
+    });
     if (result) {
       if (this.idlType.nullable) {
         const message = `Dictionary arguments cannot be nullable.`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.tokens.name, this, "no-nullable-dict-arg", message);
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)(
+          this.tokens.name,
+          this,
+          "no-nullable-dict-arg",
+          message
+        );
       } else if (!this.optional) {
-        if (this.parent && !Object(_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__["dictionaryIncludesRequiredField"])(result.dictionary, defs) && isLastRequiredArgument(this)) {
+        if (
+          this.parent &&
+          !(0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__.dictionaryIncludesRequiredField)(result.dictionary, defs) &&
+          isLastRequiredArgument(this)
+        ) {
           const message = `Dictionary argument must be optional if it has no required fields`;
-          yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.tokens.name, this, "dict-arg-optional", message, {
-            autofix: autofixDictionaryArgumentOptionality(this)
-          });
+          yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)(
+            this.tokens.name,
+            this,
+            "dict-arg-optional",
+            message,
+            {
+              autofix: autofixDictionaryArgumentOptionality(this),
+            }
+          );
         }
       } else if (!this.default) {
         const message = `Optional dictionary arguments must have a default value of \`{}\`.`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_5__["validationError"])(this.tokens.name, this, "dict-arg-default", message, {
-          autofix: autofixOptionalDictionaryDefaultValue(this)
-        });
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)(
+          this.tokens.name,
+          this,
+          "dict-arg-default",
+          message,
+          {
+            autofix: autofixOptionalDictionaryDefaultValue(this),
+          }
+        );
       }
     }
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.wrap([
+      this.extAttrs.write(w),
+      w.token(this.tokens.optional),
+      w.ts.type(this.idlType.write(w)),
+      w.token(this.tokens.variadic),
+      w.name_token(this.tokens.name, { data: this }),
+      this.default ? this.default.write(w) : "",
+      w.token(this.tokens.separator),
+    ]);
+  }
 }
 
 /**
@@ -1634,7 +1866,7 @@ class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
 function isLastRequiredArgument(arg) {
   const list = arg.parent.arguments || arg.parent.list;
   const index = list.indexOf(arg);
-  const requiredExists = list.slice(index + 1).some(a => !a.optional);
+  const requiredExists = list.slice(index + 1).some((a) => !a.optional);
   return !requiredExists;
 }
 
@@ -1643,8 +1875,12 @@ function isLastRequiredArgument(arg) {
  */
 function autofixDictionaryArgumentOptionality(arg) {
   return () => {
-    const firstToken = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_3__["getFirstToken"])(arg.idlType);
-    arg.tokens.optional = { type: "optional", value: "optional", trivia: firstToken.trivia };
+    const firstToken = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.getFirstToken)(arg.idlType);
+    arg.tokens.optional = {
+      type: "optional",
+      value: "optional",
+      trivia: firstToken.trivia,
+    };
     firstToken.trivia = " ";
     autofixOptionalDictionaryDefaultValue(arg)();
   };
@@ -1655,24 +1891,25 @@ function autofixDictionaryArgumentOptionality(arg) {
  */
 function autofixOptionalDictionaryDefaultValue(arg) {
   return () => {
-    arg.default = _default_js__WEBPACK_IMPORTED_MODULE_1__["Default"].parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_4__["Tokeniser"](" = {}"));
+    arg.default = _default_js__WEBPACK_IMPORTED_MODULE_1__.Default.parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_4__.Tokeniser(" = {}"));
   };
 }
 
 
 /***/ }),
 /* 12 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Default", function() { return Default; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Default": () => (/* binding */ Default)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
 
 
-class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -1681,16 +1918,28 @@ class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     if (!assign) {
       return null;
     }
-    const def = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["const_value"])(tokeniser) || tokeniser.consume("string", "null", "[", "{") || tokeniser.error("No value for default");
+    const def =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_value)(tokeniser) ||
+      tokeniser.consumeType("string") ||
+      tokeniser.consume("null", "[", "{") ||
+      tokeniser.error("No value for default");
     const expression = [def];
-    if (def.type === "[") {
-      const close = tokeniser.consume("]") || tokeniser.error("Default sequence value must be empty");
+    if (def.value === "[") {
+      const close =
+        tokeniser.consume("]") ||
+        tokeniser.error("Default sequence value must be empty");
       expression.push(close);
-    } else if (def.type === "{") {
-      const close = tokeniser.consume("}") || tokeniser.error("Default dictionary value must be empty");
+    } else if (def.value === "{") {
+      const close =
+        tokeniser.consume("}") ||
+        tokeniser.error("Default dictionary value must be empty");
       expression.push(close);
     }
-    return new Default({ source: tokeniser.source, tokens: { assign }, expression });
+    return new Default({
+      source: tokeniser.source,
+      tokens: { assign },
+      expression,
+    });
   }
 
   constructor({ source, tokens, expression }) {
@@ -1700,24 +1949,33 @@ class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
   }
 
   get type() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["const_data"])(this.expression[0]).type;
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).type;
   }
   get value() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["const_data"])(this.expression[0]).value;
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).value;
   }
   get negative() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["const_data"])(this.expression[0]).negative;
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).negative;
+  }
+
+  /** @param {import("../writer.js").Writer)} w */
+  write(w) {
+    return w.ts.wrap([
+      w.token(this.tokens.assign),
+      ...this.expression.map((t) => w.token(t)),
+    ]);
   }
 }
 
 
 /***/ }),
 /* 13 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Operation", function() { return Operation; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Operation": () => (/* binding */ Operation)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
@@ -1725,7 +1983,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @typedef {import("../tokeniser.js").Token} Token
    *
@@ -1736,7 +1994,9 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
    */
   static parse(tokeniser, { special, regular } = {}) {
     const tokens = { special };
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Operation({ source: tokeniser.source, tokens }));
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(
+      new Operation({ source: tokeniser.source, tokens })
+    );
     if (special && special.value === "stringifier") {
       tokens.termination = tokeniser.consume(";");
       if (tokens.termination) {
@@ -1747,12 +2007,18 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     if (!special && !regular) {
       tokens.special = tokeniser.consume("getter", "setter", "deleter");
     }
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["return_type"])(tokeniser) || tokeniser.error("Missing return type");
-    tokens.name = tokeniser.consume("identifier", "includes");
-    tokens.open = tokeniser.consume("(") || tokeniser.error("Invalid operation");
-    ret.arguments = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["argument_list"])(tokeniser);
-    tokens.close = tokeniser.consume(")") || tokeniser.error("Unterminated operation");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated operation, expected `;`");
+    ret.idlType =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser) || tokeniser.error("Missing return type");
+    tokens.name =
+      tokeniser.consumeType("identifier") || tokeniser.consume("includes");
+    tokens.open =
+      tokeniser.consume("(") || tokeniser.error("Invalid operation");
+    ret.arguments = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser);
+    tokens.close =
+      tokeniser.consume(")") || tokeniser.error("Unterminated operation");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated operation, expected `;`");
     return ret.this;
   }
 
@@ -1764,7 +2030,7 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     if (!name) {
       return "";
     }
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(name.value);
   }
   get special() {
     if (!this.tokens.special) {
@@ -1774,9 +2040,10 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
   }
 
   *validate(defs) {
+    yield* this.extAttrs.validate(defs);
     if (!this.name && ["", "static"].includes(this.special)) {
       const message = `Regular or static operations must have both a return type and an identifier.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_2__["validationError"])(this.tokens.open, this, "incomplete-op", message);
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_2__.validationError)(this.tokens.open, this, "incomplete-op", message);
     }
     if (this.idlType) {
       yield* this.idlType.validate(defs);
@@ -1785,29 +2052,70 @@ class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       yield* argument.validate(defs);
     }
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    const body = this.idlType
+      ? [
+          w.ts.type(this.idlType.write(w)),
+          w.name_token(this.tokens.name, { data: this, parent }),
+          w.token(this.tokens.open),
+          w.ts.wrap(this.arguments.map((arg) => arg.write(w))),
+          w.token(this.tokens.close),
+        ]
+      : [];
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        this.tokens.name
+          ? w.token(this.tokens.special)
+          : w.token(this.tokens.special, w.ts.nameless, { data: this, parent }),
+        ...body,
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent }
+    );
+  }
 }
 
 
 /***/ }),
 /* 14 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Attribute", function() { return Attribute; });
-/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
-/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Attribute": () => (/* binding */ Attribute)
+/* harmony export */ });
+/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
+/* harmony import */ var _validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7);
+/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
+/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
+// @ts-check
+
 
 
 
-class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+
+
+class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base {
   /**
    * @param {import("../tokeniser.js").Tokeniser} tokeniser
+   * @param {object} [options]
+   * @param {import("../tokeniser.js").Token} [options.special]
+   * @param {boolean} [options.noInherit]
+   * @param {boolean} [options.readonly]
    */
-  static parse(tokeniser, { special, noInherit = false, readonly = false } = {}) {
+  static parse(
+    tokeniser,
+    { special, noInherit = false, readonly = false } = {}
+  ) {
     const start_position = tokeniser.position;
     const tokens = { special };
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Attribute({ source: tokeniser.source, tokens }));
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)(
+      new Attribute({ source: tokeniser.source, tokens })
+    );
     if (!special && !noInherit) {
       tokens.special = tokeniser.consume("inherit");
     }
@@ -1823,13 +2131,16 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       tokeniser.unconsume(start_position);
       return;
     }
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser, "attribute-type") || tokeniser.error("Attribute lacks a type");
-    switch (ret.idlType.generic) {
-      case "sequence":
-      case "record": tokeniser.error(`Attributes cannot accept ${ret.idlType.generic} types`);
-    }
-    tokens.name = tokeniser.consume("identifier", "async", "required") || tokeniser.error("Attribute lacks a name");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated attribute, expected `;`");
+    ret.idlType =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.type_with_extended_attributes)(tokeniser, "attribute-type") ||
+      tokeniser.error("Attribute lacks a type");
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.consume("async", "required") ||
+      tokeniser.error("Attribute lacks a name");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated attribute, expected `;`");
     return ret.this;
   }
 
@@ -1846,23 +2157,70 @@ class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return !!this.tokens.readonly;
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(this.tokens.name.value);
   }
 
   *validate(defs) {
     yield* this.extAttrs.validate(defs);
     yield* this.idlType.validate(defs);
+
+    switch (this.idlType.generic) {
+      case "sequence":
+      case "record": {
+        const message = `Attributes cannot accept ${this.idlType.generic} types.`;
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(
+          this.tokens.name,
+          this,
+          "attr-invalid-type",
+          message
+        );
+        break;
+      }
+      default: {
+        const { reference } =
+          (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__.idlTypeIncludesDictionary)(this.idlType, defs) || {};
+        if (reference) {
+          const targetToken = (this.idlType.union ? reference : this.idlType)
+            .tokens.base;
+          const message = "Attributes cannot accept dictionary types.";
+          yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(
+            targetToken,
+            this,
+            "attr-invalid-type",
+            message
+          );
+        }
+      }
+    }
+  }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.special),
+        w.token(this.tokens.readonly),
+        w.token(this.tokens.base),
+        w.ts.type(this.idlType.write(w)),
+        w.name_token(this.tokens.name, { data: this, parent }),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent }
+    );
   }
 }
 
 
 /***/ }),
 /* 15 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Enum", function() { return Enum; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Enum": () => (/* binding */ Enum)
+/* harmony export */ });
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
 /* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
@@ -1870,12 +2228,12 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class EnumValue extends _token_js__WEBPACK_IMPORTED_MODULE_1__["Token"] {
+class EnumValue extends _token_js__WEBPACK_IMPORTED_MODULE_1__.WrappedToken {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
-    const value = tokeniser.consume("string");
+    const value = tokeniser.consumeType("string");
     if (value) {
       return new EnumValue({ source: tokeniser.source, tokens: { value } });
     }
@@ -1887,9 +2245,22 @@ class EnumValue extends _token_js__WEBPACK_IMPORTED_MODULE_1__["Token"] {
   get value() {
     return super.value.slice(1, -1);
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    return w.ts.wrap([
+      w.ts.trivia(this.tokens.value.trivia),
+      w.ts.definition(
+        w.ts.wrap(['"', w.ts.name(this.value, { data: this, parent }), '"']),
+        { data: this, parent }
+      ),
+      w.token(this.tokens.separator),
+    ]);
+  }
 }
 
-class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__["Base"] {
+class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -1900,23 +2271,27 @@ class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__["Base"] {
     if (!tokens.base) {
       return;
     }
-    tokens.name = tokeniser.consume("identifier") || tokeniser.error("No name for enum");
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_0__["autoParenter"])(new Enum({ source: tokeniser.source, tokens }));
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("No name for enum");
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.autoParenter)(new Enum({ source: tokeniser.source, tokens }));
     tokeniser.current = ret.this;
     tokens.open = tokeniser.consume("{") || tokeniser.error("Bodyless enum");
-    ret.values = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_0__["list"])(tokeniser, {
+    ret.values = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.list)(tokeniser, {
       parser: EnumValue.parse,
       allowDangler: true,
-      listName: "enumeration"
+      listName: "enumeration",
     });
-    if (tokeniser.probe("string")) {
+    if (tokeniser.probeType("string")) {
       tokeniser.error("No comma between enum values");
     }
-    tokens.close = tokeniser.consume("}") || tokeniser.error("Unexpected value in enum");
+    tokens.close =
+      tokeniser.consume("}") || tokeniser.error("Unexpected value in enum");
     if (!ret.values.length) {
       tokeniser.error("No value in enum");
     }
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("No semicolon after enum");
+    tokens.termination =
+      tokeniser.consume(";") || tokeniser.error("No semicolon after enum");
     return ret.this;
   }
 
@@ -1924,18 +2299,35 @@ class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__["Base"] {
     return "enum";
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_0__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.unescape)(this.tokens.name.value);
+  }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.base),
+        w.name_token(this.tokens.name, { data: this }),
+        w.token(this.tokens.open),
+        w.ts.wrap(this.values.map((v) => v.write(w))),
+        w.token(this.tokens.close),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this }
+    );
   }
 }
 
 
 /***/ }),
 /* 16 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Includes", function() { return Includes; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Includes": () => (/* binding */ Includes)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 // @ts-check
@@ -1943,12 +2335,12 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
-    const target = tokeniser.consume("identifier");
+    const target = tokeniser.consumeType("identifier");
     if (!target) {
       return;
     }
@@ -1958,8 +2350,12 @@ class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       tokeniser.unconsume(target.index);
       return;
     }
-    tokens.mixin = tokeniser.consume("identifier") || tokeniser.error("Incomplete includes statement");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("No terminating ; for includes statement");
+    tokens.mixin =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("Incomplete includes statement");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("No terminating ; for includes statement");
     return new Includes({ source: tokeniser.source, tokens });
   }
 
@@ -1967,42 +2363,63 @@ class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return "includes";
   }
   get target() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.target.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.target.value);
   }
   get includes() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.mixin.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.mixin.value);
+  }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.reference_token(this.tokens.target, this),
+        w.token(this.tokens.includes),
+        w.reference_token(this.tokens.mixin, this),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this }
+    );
   }
 }
 
 
 /***/ }),
 /* 17 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Typedef", function() { return Typedef; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Typedef": () => (/* binding */ Typedef)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
 
 
-class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
     /** @type {Base["tokens"]} */
     const tokens = {};
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Typedef({ source: tokeniser.source, tokens }));
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Typedef({ source: tokeniser.source, tokens }));
     tokens.base = tokeniser.consume("typedef");
     if (!tokens.base) {
       return;
     }
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser, "typedef-type") || tokeniser.error("Typedef lacks a type");
-    tokens.name = tokeniser.consume("identifier") || tokeniser.error("Typedef lacks a name");
+    ret.idlType =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, "typedef-type") ||
+      tokeniser.error("Typedef lacks a type");
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("Typedef lacks a name");
     tokeniser.current = ret.this;
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated typedef, expected `;`");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated typedef, expected `;`");
     return ret.this;
   }
 
@@ -2010,42 +2427,68 @@ class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return "typedef";
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value);
   }
 
   *validate(defs) {
     yield* this.idlType.validate(defs);
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.base),
+        w.ts.type(this.idlType.write(w)),
+        w.name_token(this.tokens.name, { data: this }),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this }
+    );
+  }
 }
 
 
 /***/ }),
 /* 18 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CallbackFunction", function() { return CallbackFunction; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "CallbackFunction": () => (/* binding */ CallbackFunction)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
 
 
-class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser.js").Tokeniser} tokeniser
    */
   static parse(tokeniser, base) {
     const tokens = { base };
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new CallbackFunction({ source: tokeniser.source, tokens }));
-    tokens.name = tokeniser.consume("identifier") || tokeniser.error("Callback lacks a name");
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(
+      new CallbackFunction({ source: tokeniser.source, tokens })
+    );
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("Callback lacks a name");
     tokeniser.current = ret.this;
-    tokens.assign = tokeniser.consume("=") || tokeniser.error("Callback lacks an assignment");
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["return_type"])(tokeniser) || tokeniser.error("Callback lacks a return type");
-    tokens.open = tokeniser.consume("(") || tokeniser.error("Callback lacks parentheses for arguments");
-    ret.arguments = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["argument_list"])(tokeniser);
-    tokens.close = tokeniser.consume(")") || tokeniser.error("Unterminated callback");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated callback, expected `;`");
+    tokens.assign =
+      tokeniser.consume("=") || tokeniser.error("Callback lacks an assignment");
+    ret.idlType =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser) || tokeniser.error("Callback lacks a return type");
+    tokens.open =
+      tokeniser.consume("(") ||
+      tokeniser.error("Callback lacks parentheses for arguments");
+    ret.arguments = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser);
+    tokens.close =
+      tokeniser.consume(")") || tokeniser.error("Unterminated callback");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated callback, expected `;`");
     return ret.this;
   }
 
@@ -2053,23 +2496,42 @@ class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return "callback";
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value);
   }
 
   *validate(defs) {
     yield* this.extAttrs.validate(defs);
     yield* this.idlType.validate(defs);
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.base),
+        w.name_token(this.tokens.name, { data: this }),
+        w.token(this.tokens.assign),
+        w.ts.type(this.idlType.write(w)),
+        w.token(this.tokens.open),
+        ...this.arguments.map((arg) => arg.write(w)),
+        w.token(this.tokens.close),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this }
+    );
+  }
 }
 
 
 /***/ }),
 /* 19 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Interface", function() { return Interface; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Interface": () => (/* binding */ Interface)
+/* harmony export */ });
 /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
 /* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14);
 /* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
@@ -2099,31 +2561,36 @@ __webpack_require__.r(__webpack_exports__);
 function static_member(tokeniser) {
   const special = tokeniser.consume("static");
   if (!special) return;
-  const member = _attribute_js__WEBPACK_IMPORTED_MODULE_1__["Attribute"].parse(tokeniser, { special }) ||
-    _operation_js__WEBPACK_IMPORTED_MODULE_2__["Operation"].parse(tokeniser, { special }) ||
+  const member =
+    _attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse(tokeniser, { special }) ||
+    _operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse(tokeniser, { special }) ||
     tokeniser.error("No body in static member");
   return member;
 }
 
-class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
+class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser, base, { partial = null } = {}) {
     const tokens = { partial, base };
-    return _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"].parse(tokeniser, new Interface({ source: tokeniser.source, tokens }), {
-      type: "interface",
-      inheritable: !partial,
-      allowedMembers: [
-        [_constant_js__WEBPACK_IMPORTED_MODULE_3__["Constant"].parse],
-        [_constructor_js__WEBPACK_IMPORTED_MODULE_8__["Constructor"].parse],
-        [static_member],
-        [_helpers_js__WEBPACK_IMPORTED_MODULE_5__["stringifier"]],
-        [_iterable_js__WEBPACK_IMPORTED_MODULE_4__["IterableLike"].parse],
-        [_attribute_js__WEBPACK_IMPORTED_MODULE_1__["Attribute"].parse],
-        [_operation_js__WEBPACK_IMPORTED_MODULE_2__["Operation"].parse]
-      ]
-    });
+    return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse(
+      tokeniser,
+      new Interface({ source: tokeniser.source, tokens }),
+      {
+        type: "interface",
+        inheritable: !partial,
+        allowedMembers: [
+          [_constant_js__WEBPACK_IMPORTED_MODULE_3__.Constant.parse],
+          [_constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse],
+          [static_member],
+          [_helpers_js__WEBPACK_IMPORTED_MODULE_5__.stringifier],
+          [_iterable_js__WEBPACK_IMPORTED_MODULE_4__.IterableLike.parse],
+          [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse],
+          [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse],
+        ],
+      }
+    );
   }
 
   get type() {
@@ -2134,66 +2601,100 @@ class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
     yield* this.extAttrs.validate(defs);
     if (
       !this.partial &&
-      this.extAttrs.every(extAttr => extAttr.name !== "Exposed") &&
-      this.extAttrs.every(extAttr => extAttr.name !== "LegacyNoInterfaceObject")
+      this.extAttrs.every((extAttr) => extAttr.name !== "Exposed")
     ) {
       const message = `Interfaces must have \`[Exposed]\` extended attribute. \
 To fix, add, for example, \`[Exposed=Window]\`. Please also consider carefully \
 if your interface should also be exposed in a Worker scope. Refer to the \
 [WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \
 for more information.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(this.tokens.name, this, "require-exposed", message, {
-        autofix: Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["autofixAddExposedWindow"])(this)
-      });
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)(
+        this.tokens.name,
+        this,
+        "require-exposed",
+        message,
+        {
+          autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autofixAddExposedWindow)(this),
+        }
+      );
     }
-    const oldConstructors = this.extAttrs.filter(extAttr => extAttr.name === "Constructor");
+    const oldConstructors = this.extAttrs.filter(
+      (extAttr) => extAttr.name === "Constructor"
+    );
     for (const constructor of oldConstructors) {
       const message = `Constructors should now be represented as a \`constructor()\` operation on the interface \
 instead of \`[Constructor]\` extended attribute. Refer to the \
 [WebIDL spec section on constructor operations](https://heycam.github.io/webidl/#idl-constructors) \
 for more information.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(constructor.tokens.name, this, "constructor-member", message, {
-        autofix: autofixConstructor(this, constructor)
-      });
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)(
+        constructor.tokens.name,
+        this,
+        "constructor-member",
+        message,
+        {
+          autofix: autofixConstructor(this, constructor),
+        }
+      );
     }
 
-    const isGlobal = this.extAttrs.some(extAttr => extAttr.name === "Global");
+    const isGlobal = this.extAttrs.some((extAttr) => extAttr.name === "Global");
     if (isGlobal) {
-      const factoryFunctions = this.extAttrs.filter(extAttr => extAttr.name === "LegacyFactoryFunction");
+      const factoryFunctions = this.extAttrs.filter(
+        (extAttr) => extAttr.name === "LegacyFactoryFunction"
+      );
       for (const named of factoryFunctions) {
         const message = `Interfaces marked as \`[Global]\` cannot have factory functions.`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(named.tokens.name, this, "no-constructible-global", message);
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)(
+          named.tokens.name,
+          this,
+          "no-constructible-global",
+          message
+        );
       }
 
-      const constructors = this.members.filter(member => member.type === "constructor");
+      const constructors = this.members.filter(
+        (member) => member.type === "constructor"
+      );
       for (const named of constructors) {
         const message = `Interfaces marked as \`[Global]\` cannot have constructors.`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_6__["validationError"])(named.tokens.base, this, "no-constructible-global", message);
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)(
+          named.tokens.base,
+          this,
+          "no-constructible-global",
+          message
+        );
       }
     }
 
     yield* super.validate(defs);
     if (!this.partial) {
-      yield* Object(_validators_interface_js__WEBPACK_IMPORTED_MODULE_7__["checkInterfaceMemberDuplication"])(defs, this);
+      yield* (0,_validators_interface_js__WEBPACK_IMPORTED_MODULE_7__.checkInterfaceMemberDuplication)(defs, this);
     }
   }
 }
 
 function autofixConstructor(interfaceDef, constructorExtAttr) {
-  interfaceDef = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["autoParenter"])(interfaceDef);
+  interfaceDef = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autoParenter)(interfaceDef);
   return () => {
-    const indentation = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["getLastIndentation"])(interfaceDef.extAttrs.tokens.open.trivia);
-    const memberIndent = interfaceDef.members.length ?
-      Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["getLastIndentation"])(Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["getFirstToken"])(interfaceDef.members[0]).trivia) :
-      Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["getMemberIndentation"])(indentation);
-    const constructorOp = _constructor_js__WEBPACK_IMPORTED_MODULE_8__["Constructor"].parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__["Tokeniser"](`\n${memberIndent}constructor();`));
-    constructorOp.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_10__["ExtendedAttributes"]({});
-    Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["autoParenter"])(constructorOp).arguments = constructorExtAttr.arguments;
-
-    const existingIndex = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_5__["findLastIndex"])(interfaceDef.members, m => m.type === "constructor");
+    const indentation = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)(
+      interfaceDef.extAttrs.tokens.open.trivia
+    );
+    const memberIndent = interfaceDef.members.length
+      ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)((0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getFirstToken)(interfaceDef.members[0]).trivia)
+      : (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getMemberIndentation)(indentation);
+    const constructorOp = _constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse(
+      new _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__.Tokeniser(`\n${memberIndent}constructor();`)
+    );
+    constructorOp.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_10__.ExtendedAttributes({});
+    (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autoParenter)(constructorOp).arguments = constructorExtAttr.arguments;
+
+    const existingIndex = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.findLastIndex)(
+      interfaceDef.members,
+      (m) => m.type === "constructor"
+    );
     interfaceDef.members.splice(existingIndex + 1, 0, constructorOp);
 
-    const { close }  = interfaceDef.tokens;
+    const { close } = interfaceDef.tokens;
     if (!close.trivia.includes("\n")) {
       close.trivia += `\n${indentation}`;
     }
@@ -2214,11 +2715,12 @@ function autofixConstructor(interfaceDef, constructorExtAttr) {
 
 /***/ }),
 /* 20 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Container": () => (/* binding */ Container)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
@@ -2234,79 +2736,119 @@ function inheritance(tokeniser) {
   if (!colon) {
     return {};
   }
-  const inheritance = tokeniser.consume("identifier") || tokeniser.error("Inheritance lacks a type");
+  const inheritance =
+    tokeniser.consumeType("identifier") ||
+    tokeniser.error("Inheritance lacks a type");
   return { colon, inheritance };
 }
 
-class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
-    /**
-     * @template T
-     * @param {import("../tokeniser.js").Tokeniser} tokeniser
-     * @param {T} instance
-     * @param {*} args
-     */
-    static parse(tokeniser, instance, { type, inheritable, allowedMembers }) {
-      const { tokens } = instance;
-      tokens.name = tokeniser.consume("identifier") || tokeniser.error(`Missing name in ${instance.type}`);
-      tokeniser.current = instance;
-      instance = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["autoParenter"])(instance);
-      if (inheritable) {
-        Object.assign(tokens, inheritance(tokeniser));
+class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
+  /**
+   * @template T
+   * @param {import("../tokeniser.js").Tokeniser} tokeniser
+   * @param {T} instance
+   * @param {*} args
+   */
+  static parse(tokeniser, instance, { type, inheritable, allowedMembers }) {
+    const { tokens } = instance;
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error(`Missing name in ${instance.type}`);
+    tokeniser.current = instance;
+    instance = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(instance);
+    if (inheritable) {
+      Object.assign(tokens, inheritance(tokeniser));
+    }
+    tokens.open = tokeniser.consume("{") || tokeniser.error(`Bodyless ${type}`);
+    instance.members = [];
+    while (true) {
+      tokens.close = tokeniser.consume("}");
+      if (tokens.close) {
+        tokens.termination =
+          tokeniser.consume(";") ||
+          tokeniser.error(`Missing semicolon after ${type}`);
+        return instance.this;
       }
-      tokens.open = tokeniser.consume("{") || tokeniser.error(`Bodyless ${type}`);
-      instance.members = [];
-      while (true) {
-        tokens.close = tokeniser.consume("}");
-        if (tokens.close) {
-          tokens.termination = tokeniser.consume(";") || tokeniser.error(`Missing semicolon after ${type}`);
-          return instance.this;
-        }
-        const ea = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__["ExtendedAttributes"].parse(tokeniser);
-        let mem;
-        for (const [parser, ...args] of allowedMembers) {
-          mem = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["autoParenter"])(parser(tokeniser, ...args));
-          if (mem) {
-            break;
-          }
-        }
-        if (!mem) {
-          tokeniser.error("Unknown member");
+      const ea = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__.ExtendedAttributes.parse(tokeniser);
+      let mem;
+      for (const [parser, ...args] of allowedMembers) {
+        mem = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(parser(tokeniser, ...args));
+        if (mem) {
+          break;
         }
-        mem.extAttrs = ea;
-        instance.members.push(mem.this);
       }
+      if (!mem) {
+        tokeniser.error("Unknown member");
+      }
+      mem.extAttrs = ea;
+      instance.members.push(mem.this);
     }
+  }
 
-    get partial() {
-      return !!this.tokens.partial;
-    }
-    get name() {
-      return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["unescape"])(this.tokens.name.value);
+  get partial() {
+    return !!this.tokens.partial;
+  }
+  get name() {
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.name.value);
+  }
+  get inheritance() {
+    if (!this.tokens.inheritance) {
+      return null;
     }
-    get inheritance() {
-      if (!this.tokens.inheritance) {
-        return null;
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.inheritance.value);
+  }
+
+  *validate(defs) {
+    for (const member of this.members) {
+      if (member.validate) {
+        yield* member.validate(defs);
       }
-      return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["unescape"])(this.tokens.inheritance.value);
     }
+  }
 
-    *validate(defs) {
-      for (const member of this.members) {
-        if (member.validate) {
-          yield* member.validate(defs);
-        }
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const inheritance = () => {
+      if (!this.tokens.inheritance) {
+        return "";
       }
-    }
+      return w.ts.wrap([
+        w.token(this.tokens.colon),
+        w.ts.trivia(this.tokens.inheritance.trivia),
+        w.ts.inheritance(
+          w.reference(this.tokens.inheritance.value, { context: this })
+        ),
+      ]);
+    };
+
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.callback),
+        w.token(this.tokens.partial),
+        w.token(this.tokens.base),
+        w.token(this.tokens.mixin),
+        w.name_token(this.tokens.name, { data: this }),
+        inheritance(),
+        w.token(this.tokens.open),
+        w.ts.wrap(this.members.map((m) => m.write(w))),
+        w.token(this.tokens.close),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this }
+    );
   }
+}
 
 
 /***/ }),
 /* 21 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Constant", function() { return Constant; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Constant": () => (/* binding */ Constant)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
@@ -2314,7 +2856,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser.js").Tokeniser} tokeniser
    */
@@ -2325,21 +2867,29 @@ class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     if (!tokens.base) {
       return;
     }
-    let idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["primitive_type"])(tokeniser);
+    let idlType = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.primitive_type)(tokeniser);
     if (!idlType) {
-      const base = tokeniser.consume("identifier") || tokeniser.error("Const lacks a type");
-      idlType = new _type_js__WEBPACK_IMPORTED_MODULE_1__["Type"]({ source: tokeniser.source, tokens: { base } });
+      const base =
+        tokeniser.consumeType("identifier") ||
+        tokeniser.error("Const lacks a type");
+      idlType = new _type_js__WEBPACK_IMPORTED_MODULE_1__.Type({ source: tokeniser.source, tokens: { base } });
     }
     if (tokeniser.probe("?")) {
       tokeniser.error("Unexpected nullable constant type");
     }
     idlType.type = "const-type";
-    tokens.name = tokeniser.consume("identifier") || tokeniser.error("Const lacks a name");
-    tokens.assign = tokeniser.consume("=") || tokeniser.error("Const lacks value assignment");
-    tokens.value = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["const_value"])(tokeniser) || tokeniser.error("Const lacks a value");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated const, expected `;`");
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("Const lacks a name");
+    tokens.assign =
+      tokeniser.consume("=") || tokeniser.error("Const lacks value assignment");
+    tokens.value =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.const_value)(tokeniser) || tokeniser.error("Const lacks a value");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated const, expected `;`");
     const ret = new Constant({ source: tokeniser.source, tokens });
-    Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["autoParenter"])(ret).idlType = idlType;
+    (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(ret).idlType = idlType;
     return ret;
   }
 
@@ -2347,42 +2897,63 @@ class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return "const";
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.name.value);
   }
   get value() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_2__["const_data"])(this.tokens.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.const_data)(this.tokens.value);
+  }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.base),
+        w.ts.type(this.idlType.write(w)),
+        w.name_token(this.tokens.name, { data: this, parent }),
+        w.token(this.tokens.assign),
+        w.token(this.tokens.value),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent }
+    );
   }
 }
 
 
 /***/ }),
 /* 22 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IterableLike", function() { return IterableLike; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "IterableLike": () => (/* binding */ IterableLike)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
 
 
-class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser.js").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
     const start_position = tokeniser.position;
     const tokens = {};
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new IterableLike({ source: tokeniser.source, tokens }));
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(
+      new IterableLike({ source: tokeniser.source, tokens })
+    );
     tokens.readonly = tokeniser.consume("readonly");
     if (!tokens.readonly) {
       tokens.async = tokeniser.consume("async");
     }
-    tokens.base =
-      tokens.readonly ? tokeniser.consume("maplike", "setlike") :
-      tokens.async ? tokeniser.consume("iterable") :
-      tokeniser.consume("iterable", "maplike", "setlike");
+    tokens.base = tokens.readonly
+      ? tokeniser.consume("maplike", "setlike")
+      : tokens.async
+      ? tokeniser.consume("iterable")
+      : tokeniser.consume("iterable", "maplike", "setlike");
     if (!tokens.base) {
       tokeniser.unconsume(start_position);
       return;
@@ -2393,34 +2964,43 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     const secondTypeAllowed = secondTypeRequired || type === "iterable";
     const argumentAllowed = ret.async && type === "iterable";
 
-    tokens.open = tokeniser.consume("<") || tokeniser.error(`Missing less-than sign \`<\` in ${type} declaration`);
-    const first = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser) || tokeniser.error(`Missing a type argument in ${type} declaration`);
+    tokens.open =
+      tokeniser.consume("<") ||
+      tokeniser.error(`Missing less-than sign \`<\` in ${type} declaration`);
+    const first =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) ||
+      tokeniser.error(`Missing a type argument in ${type} declaration`);
     ret.idlType = [first];
     ret.arguments = [];
 
     if (secondTypeAllowed) {
       first.tokens.separator = tokeniser.consume(",");
       if (first.tokens.separator) {
-        ret.idlType.push(Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser));
-      }
-      else if (secondTypeRequired) {
+        ret.idlType.push((0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser));
+      } else if (secondTypeRequired) {
         tokeniser.error(`Missing second type argument in ${type} declaration`);
       }
     }
 
-    tokens.close = tokeniser.consume(">") || tokeniser.error(`Missing greater-than sign \`>\` in ${type} declaration`);
+    tokens.close =
+      tokeniser.consume(">") ||
+      tokeniser.error(`Missing greater-than sign \`>\` in ${type} declaration`);
 
     if (tokeniser.probe("(")) {
       if (argumentAllowed) {
         tokens.argsOpen = tokeniser.consume("(");
-        ret.arguments.push(...Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["argument_list"])(tokeniser));
-        tokens.argsClose = tokeniser.consume(")") || tokeniser.error("Unterminated async iterable argument list");
+        ret.arguments.push(...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser));
+        tokens.argsClose =
+          tokeniser.consume(")") ||
+          tokeniser.error("Unterminated async iterable argument list");
       } else {
         tokeniser.error(`Arguments are only allowed for \`async iterable\``);
       }
     }
 
-    tokens.termination = tokeniser.consume(";") || tokeniser.error(`Missing semicolon after ${type} declaration`);
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error(`Missing semicolon after ${type} declaration`);
 
     return ret.this;
   }
@@ -2443,23 +3023,44 @@ class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       yield* argument.validate(defs);
     }
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.readonly),
+        w.token(this.tokens.async),
+        w.token(this.tokens.base, w.ts.generic),
+        w.token(this.tokens.open),
+        w.ts.wrap(this.idlType.map((t) => t.write(w))),
+        w.token(this.tokens.close),
+        w.token(this.tokens.argsOpen),
+        w.ts.wrap(this.arguments.map((arg) => arg.write(w))),
+        w.token(this.tokens.argsClose),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent: this.parent }
+    );
+  }
 }
 
 
 /***/ }),
 /* 23 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checkInterfaceMemberDuplication", function() { return checkInterfaceMemberDuplication; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "checkInterfaceMemberDuplication": () => (/* binding */ checkInterfaceMemberDuplication)
+/* harmony export */ });
 /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
 // @ts-check
 
 
 
 function* checkInterfaceMemberDuplication(defs, i) {
-  const opNames = new Set(getOperations(i).map(op => op.name));
+  const opNames = new Set(getOperations(i).map((op) => op.name));
   const partials = defs.partials.get(i.name) || [];
   const mixins = defs.mixinMap.get(i.name) || [];
   for (const ext of [...partials, ...mixins]) {
@@ -2475,31 +3076,36 @@ function* checkInterfaceMemberDuplication(defs, i) {
       const { name } = addition;
       if (name && existings.has(name)) {
         const message = `The operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`;
-        yield Object(_error_js__WEBPACK_IMPORTED_MODULE_0__["validationError"])(addition.tokens.name, ext, "no-cross-overload", message);
+        yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(
+          addition.tokens.name,
+          ext,
+          "no-cross-overload",
+          message
+        );
       }
     }
   }
 
   function getOperations(i) {
-    return i.members
-      .filter(({type}) => type === "operation");
+    return i.members.filter(({ type }) => type === "operation");
   }
 }
 
 
 /***/ }),
 /* 24 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Constructor", function() { return Constructor; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Constructor": () => (/* binding */ Constructor)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 
 
 
-class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -2510,12 +3116,17 @@ class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     }
     /** @type {Base["tokens"]} */
     const tokens = { base };
-    tokens.open = tokeniser.consume("(") || tokeniser.error("No argument list in constructor");
-    const args = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["argument_list"])(tokeniser);
-    tokens.close = tokeniser.consume(")") || tokeniser.error("Unterminated constructor");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("No semicolon after constructor");
+    tokens.open =
+      tokeniser.consume("(") ||
+      tokeniser.error("No argument list in constructor");
+    const args = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser);
+    tokens.close =
+      tokeniser.consume(")") || tokeniser.error("Unterminated constructor");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("No semicolon after constructor");
     const ret = new Constructor({ source: tokeniser.source, tokens });
-    Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(ret).arguments = args;
+    (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(ret).arguments = args;
     return ret;
   }
 
@@ -2531,16 +3142,33 @@ class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
       yield* argument.validate(defs);
     }
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.base, w.ts.nameless, { data: this, parent }),
+        w.token(this.tokens.open),
+        w.ts.wrap(this.arguments.map((arg) => arg.write(w))),
+        w.token(this.tokens.close),
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent }
+    );
+  }
 }
 
 
 /***/ }),
 /* 25 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Mixin", function() { return Mixin; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Mixin": () => (/* binding */ Mixin)
+/* harmony export */ });
 /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
 /* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21);
 /* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14);
@@ -2552,7 +3180,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
+class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container {
   /**
    * @typedef {import("../tokeniser.js").Token} Token
    *
@@ -2567,15 +3195,19 @@ class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
     if (!tokens.mixin) {
       return;
     }
-    return _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"].parse(tokeniser, new Mixin({ source: tokeniser.source, tokens }), {
-      type: "interface mixin",
-      allowedMembers: [
-        [_constant_js__WEBPACK_IMPORTED_MODULE_1__["Constant"].parse],
-        [_helpers_js__WEBPACK_IMPORTED_MODULE_4__["stringifier"]],
-        [_attribute_js__WEBPACK_IMPORTED_MODULE_2__["Attribute"].parse, { noInherit: true }],
-        [_operation_js__WEBPACK_IMPORTED_MODULE_3__["Operation"].parse, { regular: true }]
-      ]
-    });
+    return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse(
+      tokeniser,
+      new Mixin({ source: tokeniser.source, tokens }),
+      {
+        type: "interface mixin",
+        allowedMembers: [
+          [_constant_js__WEBPACK_IMPORTED_MODULE_1__.Constant.parse],
+          [_helpers_js__WEBPACK_IMPORTED_MODULE_4__.stringifier],
+          [_attribute_js__WEBPACK_IMPORTED_MODULE_2__.Attribute.parse, { noInherit: true }],
+          [_operation_js__WEBPACK_IMPORTED_MODULE_3__.Operation.parse, { regular: true }],
+        ],
+      }
+    );
   }
 
   get type() {
@@ -2586,11 +3218,12 @@ class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
 
 /***/ }),
 /* 26 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Dictionary", function() { return Dictionary; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Dictionary": () => (/* binding */ Dictionary)
+/* harmony export */ });
 /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
 /* harmony import */ var _field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27);
 // @ts-check
@@ -2598,7 +3231,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
+class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    * @param {object} [options]
@@ -2610,13 +3243,15 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
     if (!tokens.base) {
       return;
     }
-    return _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"].parse(tokeniser, new Dictionary({ source: tokeniser.source, tokens }), {
-      type: "dictionary",
-      inheritable: !partial,
-      allowedMembers: [
-        [_field_js__WEBPACK_IMPORTED_MODULE_1__["Field"].parse],
-      ]
-    });
+    return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse(
+      tokeniser,
+      new Dictionary({ source: tokeniser.source, tokens }),
+      {
+        type: "dictionary",
+        inheritable: !partial,
+        allowedMembers: [[_field_js__WEBPACK_IMPORTED_MODULE_1__.Field.parse]],
+      }
+    );
   }
 
   get type() {
@@ -2627,11 +3262,12 @@ class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
 
 /***/ }),
 /* 27 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Field", function() { return Field; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Field": () => (/* binding */ Field)
+/* harmony export */ });
 /* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8);
@@ -2641,21 +3277,28 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
+class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
   static parse(tokeniser) {
     /** @type {Base["tokens"]} */
     const tokens = {};
-    const ret = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["autoParenter"])(new Field({ source: tokeniser.source, tokens }));
-    ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__["ExtendedAttributes"].parse(tokeniser);
+    const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Field({ source: tokeniser.source, tokens }));
+    ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser);
     tokens.required = tokeniser.consume("required");
-    ret.idlType = Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["type_with_extended_attributes"])(tokeniser, "dictionary-type") || tokeniser.error("Dictionary member lacks a type");
-    tokens.name = tokeniser.consume("identifier") || tokeniser.error("Dictionary member lacks a name");
-    ret.default = _default_js__WEBPACK_IMPORTED_MODULE_3__["Default"].parse(tokeniser);
-    if (tokens.required && ret.default) tokeniser.error("Required member must not have a default");
-    tokens.termination = tokeniser.consume(";") || tokeniser.error("Unterminated dictionary member, expected `;`");
+    ret.idlType =
+      (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, "dictionary-type") ||
+      tokeniser.error("Dictionary member lacks a type");
+    tokens.name =
+      tokeniser.consumeType("identifier") ||
+      tokeniser.error("Dictionary member lacks a name");
+    ret.default = _default_js__WEBPACK_IMPORTED_MODULE_3__.Default.parse(tokeniser);
+    if (tokens.required && ret.default)
+      tokeniser.error("Required member must not have a default");
+    tokens.termination =
+      tokeniser.consume(";") ||
+      tokeniser.error("Unterminated dictionary member, expected `;`");
     return ret.this;
   }
 
@@ -2663,7 +3306,7 @@ class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
     return "field";
   }
   get name() {
-    return Object(_helpers_js__WEBPACK_IMPORTED_MODULE_1__["unescape"])(this.tokens.name.value);
+    return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value);
   }
   get required() {
     return !!this.tokens.required;
@@ -2672,28 +3315,47 @@ class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__["Base"] {
   *validate(defs) {
     yield* this.idlType.validate(defs);
   }
+
+  /** @param {import("../writer.js").Writer} w */
+  write(w) {
+    const { parent } = this;
+    return w.ts.definition(
+      w.ts.wrap([
+        this.extAttrs.write(w),
+        w.token(this.tokens.required),
+        w.ts.type(this.idlType.write(w)),
+        w.name_token(this.tokens.name, { data: this, parent }),
+        this.default ? this.default.write(w) : "",
+        w.token(this.tokens.termination),
+      ]),
+      { data: this, parent }
+    );
+  }
 }
 
 
 /***/ }),
 /* 28 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Namespace", function() { return Namespace; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Namespace": () => (/* binding */ Namespace)
+/* harmony export */ });
 /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
 /* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14);
 /* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
 /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3);
 /* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4);
+/* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21);
 
 
 
 
 
 
-class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
+
+class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    * @param {object} [options]
@@ -2705,13 +3367,18 @@ class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
     if (!tokens.base) {
       return;
     }
-    return _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"].parse(tokeniser, new Namespace({ source: tokeniser.source, tokens }), {
-      type: "namespace",
-      allowedMembers: [
-        [_attribute_js__WEBPACK_IMPORTED_MODULE_1__["Attribute"].parse, { noInherit: true, readonly: true }],
-        [_operation_js__WEBPACK_IMPORTED_MODULE_2__["Operation"].parse, { regular: true }]
-      ]
-    });
+    return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse(
+      tokeniser,
+      new Namespace({ source: tokeniser.source, tokens }),
+      {
+        type: "namespace",
+        allowedMembers: [
+          [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse, { noInherit: true, readonly: true }],
+          [_constant_js__WEBPACK_IMPORTED_MODULE_5__.Constant.parse],
+          [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse, { regular: true }],
+        ],
+      }
+    );
   }
 
   get type() {
@@ -2719,15 +3386,24 @@ class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"]
   }
 
   *validate(defs) {
-    if (!this.partial && this.extAttrs.every(extAttr => extAttr.name !== "Exposed")) {
+    if (
+      !this.partial &&
+      this.extAttrs.every((extAttr) => extAttr.name !== "Exposed")
+    ) {
       const message = `Namespaces must have [Exposed] extended attribute. \
 To fix, add, for example, [Exposed=Window]. Please also consider carefully \
 if your namespace should also be exposed in a Worker scope. Refer to the \
 [WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \
 for more information.`;
-      yield Object(_error_js__WEBPACK_IMPORTED_MODULE_3__["validationError"])(this.tokens.name, this, "require-exposed", message, {
-        autofix: Object(_helpers_js__WEBPACK_IMPORTED_MODULE_4__["autofixAddExposedWindow"])(this)
-      });
+      yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)(
+        this.tokens.name,
+        this,
+        "require-exposed",
+        message,
+        {
+          autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_4__.autofixAddExposedWindow)(this),
+        }
+      );
     }
     yield* super.validate(defs);
   }
@@ -2736,11 +3412,12 @@ for more information.`;
 
 /***/ }),
 /* 29 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CallbackInterface", function() { return CallbackInterface; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "CallbackInterface": () => (/* binding */ CallbackInterface)
+/* harmony export */ });
 /* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20);
 /* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13);
 /* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21);
@@ -2750,7 +3427,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
-class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"] {
+class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container {
   /**
    * @param {import("../tokeniser").Tokeniser} tokeniser
    */
@@ -2760,14 +3437,18 @@ class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Cont
     if (!tokens.base) {
       return;
     }
-    return _container_js__WEBPACK_IMPORTED_MODULE_0__["Container"].parse(tokeniser, new CallbackInterface({ source: tokeniser.source, tokens }), {
-      type: "callback interface",
-      inheritable: !partial,
-      allowedMembers: [
-        [_constant_js__WEBPACK_IMPORTED_MODULE_2__["Constant"].parse],
-        [_operation_js__WEBPACK_IMPORTED_MODULE_1__["Operation"].parse, { regular: true }]
-      ]
-    });
+    return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse(
+      tokeniser,
+      new CallbackInterface({ source: tokeniser.source, tokens }),
+      {
+        type: "callback interface",
+        inheritable: !partial,
+        allowedMembers: [
+          [_constant_js__WEBPACK_IMPORTED_MODULE_2__.Constant.parse],
+          [_operation_js__WEBPACK_IMPORTED_MODULE_1__.Operation.parse, { regular: true }],
+        ],
+      }
+    );
   }
 
   get type() {
@@ -2778,19 +3459,19 @@ class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__["Cont
 
 /***/ }),
 /* 30 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "write", function() { return write; });
-
-
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "Writer": () => (/* binding */ Writer),
+/* harmony export */   "write": () => (/* binding */ write)
+/* harmony export */ });
 function noop(arg) {
   return arg;
 }
 
 const templates = {
-  wrap: items => items.join(""),
+  wrap: (items) => items.join(""),
   trivia: noop,
   name: noop,
   reference: noop,
@@ -2800,335 +3481,74 @@ const templates = {
   inheritance: noop,
   definition: noop,
   extendedAttribute: noop,
-  extendedAttributeReference: noop
+  extendedAttributeReference: noop,
 };
 
-function write(ast, { templates: ts = templates } = {}) {
-  ts = Object.assign({}, templates, ts);
+class Writer {
+  constructor(ts) {
+    this.ts = Object.assign({}, templates, ts);
+  }
 
-  function reference(raw, { unescaped, context }) {
+  reference(raw, { unescaped, context }) {
     if (!unescaped) {
       unescaped = raw.startsWith("_") ? raw.slice(1) : raw;
     }
-    return ts.reference(raw, unescaped, context);
+    return this.ts.reference(raw, unescaped, context);
   }
 
-  function token(t, wrapper = noop, ...args) {
+  token(t, wrapper = noop, ...args) {
     if (!t) {
       return "";
     }
     const value = wrapper(t.value, ...args);
-    return ts.wrap([ts.trivia(t.trivia), value]);
+    return this.ts.wrap([this.ts.trivia(t.trivia), value]);
   }
 
-  function reference_token(t, context) {
-    return token(t, reference, { context });
+  reference_token(t, context) {
+    return this.token(t, this.reference.bind(this), { context });
   }
 
-  function name_token(t, arg) {
-    return token(t, ts.name, arg);
+  name_token(t, arg) {
+    return this.token(t, this.ts.name, arg);
   }
 
-  function type_body(it) {
-    if (it.union || it.generic) {
-      return ts.wrap([
-        token(it.tokens.base, ts.generic),
-        token(it.tokens.open),
-        ...it.subtype.map(type),
-        token(it.tokens.close)
-      ]);
-    }
-    const firstToken = it.tokens.prefix || it.tokens.base;
-    const prefix = it.tokens.prefix ? [
-      it.tokens.prefix.value,
-      ts.trivia(it.tokens.base.trivia)
-    ] : [];
-    const ref = reference(ts.wrap([
-      ...prefix,
-      it.tokens.base.value,
-      token(it.tokens.postfix)
-    ]), { unescaped: it.idlType, context: it });
-    return ts.wrap([ts.trivia(firstToken.trivia), ref]);
-  }
-  function type(it) {
-    return ts.wrap([
-      extended_attributes(it.extAttrs),
-      type_body(it),
-      token(it.tokens.nullable),
-      token(it.tokens.separator)
-    ]);
-  }
-  function default_(def) {
-    if (!def) {
-      return "";
-    }
-    return ts.wrap([
-      token(def.tokens.assign),
-      ...def.expression.map(t => token(t))
-    ]);
-  }
-  function argument(arg) {
-    return ts.wrap([
-      extended_attributes(arg.extAttrs),
-      token(arg.tokens.optional),
-      ts.type(type(arg.idlType)),
-      token(arg.tokens.variadic),
-      name_token(arg.tokens.name, { data: arg }),
-      default_(arg.default),
-      token(arg.tokens.separator)
-    ]);
-  }
-  function extended_attribute_listitem(str) {
-    return ts.wrap([
-      token(str.tokens.value),
-      token(str.tokens.separator)
-    ]);
-  }
-  function identifier(id, context) {
-    return ts.wrap([
-      reference_token(id.tokens.value, context),
-      token(id.tokens.separator)
-    ]);
-  }
-  function make_ext_at(it) {
-    const { rhsType } = it.params;
-    return ts.wrap([
-      ts.trivia(it.tokens.name.trivia),
-      ts.extendedAttribute(ts.wrap([
-        ts.extendedAttributeReference(it.name),
-        token(it.params.tokens.assign),
-        reference_token(it.params.tokens.secondaryName, it),
-        token(it.params.tokens.open),
-        ...!it.params.list ? [] :
-          it.params.list.map(
-            rhsType === "identifier-list" ? id => identifier(id, it) :
-            rhsType && rhsType.endsWith("-list") ? extended_attribute_listitem :
-            argument
-          ),
-        token(it.params.tokens.close)
-      ])),
-      token(it.tokens.separator)
-    ]);
-  }
-  function extended_attributes(eats) {
-    if (!eats.length) return "";
-    return ts.wrap([
-      token(eats.tokens.open),
-      ...eats.map(make_ext_at),
-      token(eats.tokens.close)
+  identifier(id, context) {
+    return this.ts.wrap([
+      this.reference_token(id.tokens.value, context),
+      this.token(id.tokens.separator),
     ]);
   }
+}
 
-  function operation(it, parent) {
-    const body = it.idlType ? [
-      ts.type(type(it.idlType)),
-      name_token(it.tokens.name, { data: it, parent }),
-      token(it.tokens.open),
-      ts.wrap(it.arguments.map(argument)),
-      token(it.tokens.close),
-    ] : [];
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      it.tokens.name ? token(it.tokens.special) : token(it.tokens.special, ts.nameless, { data: it, parent }),
-      ...body,
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-
-  function attribute(it, parent) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.special),
-      token(it.tokens.readonly),
-      token(it.tokens.base),
-      ts.type(type(it.idlType)),
-      name_token(it.tokens.name, { data: it, parent }),
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-
-  function constructor(it, parent) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.base, ts.nameless, { data: it, parent }),
-      token(it.tokens.open),
-      ts.wrap(it.arguments.map(argument)),
-      token(it.tokens.close),
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-
-  function inheritance(inh) {
-    if (!inh.tokens.inheritance) {
-      return "";
-    }
-    return ts.wrap([
-      token(inh.tokens.colon),
-      ts.trivia(inh.tokens.inheritance.trivia),
-      ts.inheritance(reference(inh.tokens.inheritance.value, { context: inh }))
-    ]);
-  }
+function write(ast, { templates: ts = templates } = {}) {
+  ts = Object.assign({}, templates, ts);
 
-  function container(it) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.callback),
-      token(it.tokens.partial),
-      token(it.tokens.base),
-      token(it.tokens.mixin),
-      name_token(it.tokens.name, { data: it }),
-      inheritance(it),
-      token(it.tokens.open),
-      iterate(it.members, it),
-      token(it.tokens.close),
-      token(it.tokens.termination)
-    ]), { data: it });
-  }
-
-  function field(it, parent) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.required),
-      ts.type(type(it.idlType)),
-      name_token(it.tokens.name, { data: it, parent }),
-      default_(it.default),
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-  function const_(it, parent) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.base),
-      ts.type(type(it.idlType)),
-      name_token(it.tokens.name, { data: it, parent }),
-      token(it.tokens.assign),
-      token(it.tokens.value),
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-  function typedef(it) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.base),
-      ts.type(type(it.idlType)),
-      name_token(it.tokens.name, { data: it }),
-      token(it.tokens.termination)
-    ]), { data: it });
-  }
-  function includes(it) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      reference_token(it.tokens.target, it),
-      token(it.tokens.includes),
-      reference_token(it.tokens.mixin, it),
-      token(it.tokens.termination)
-    ]), { data: it });
-  }
-  function callback(it) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.base),
-      name_token(it.tokens.name, { data: it }),
-      token(it.tokens.assign),
-      ts.type(type(it.idlType)),
-      token(it.tokens.open),
-      ...it.arguments.map(argument),
-      token(it.tokens.close),
-      token(it.tokens.termination),
-    ]), { data: it });
-  }
-  function enum_(it) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.base),
-      name_token(it.tokens.name, { data: it }),
-      token(it.tokens.open),
-      iterate(it.values, it),
-      token(it.tokens.close),
-      token(it.tokens.termination)
-    ]), { data: it });
-  }
-  function enum_value(v, parent) {
-    return ts.wrap([
-      ts.trivia(v.tokens.value.trivia),
-      ts.definition(
-        ts.wrap(['"', ts.name(v.value, { data: v, parent }), '"']),
-        { data: v, parent }
-      ),
-      token(v.tokens.separator)
-    ]);
-  }
-  function iterable_like(it, parent) {
-    return ts.definition(ts.wrap([
-      extended_attributes(it.extAttrs),
-      token(it.tokens.readonly),
-      token(it.tokens.async),
-      token(it.tokens.base, ts.generic),
-      token(it.tokens.open),
-      ts.wrap(it.idlType.map(type)),
-      token(it.tokens.close),
-      token(it.tokens.argsOpen),
-      ts.wrap(it.arguments.map(argument)),
-      token(it.tokens.argsClose),
-      token(it.tokens.termination)
-    ]), { data: it, parent });
-  }
-  function eof(it) {
-    return ts.trivia(it.trivia);
-  }
-
-  const table = {
-    interface: container,
-    "interface mixin": container,
-    namespace: container,
-    operation,
-    attribute,
-    constructor,
-    dictionary: container,
-    field,
-    const: const_,
-    typedef,
-    includes,
-    callback,
-    enum: enum_,
-    "enum-value": enum_value,
-    iterable: iterable_like,
-    maplike: iterable_like,
-    setlike: iterable_like,
-    "callback interface": container,
-    eof
-  };
-  function dispatch(it, parent) {
-    const dispatcher = table[it.type];
-    if (!dispatcher) {
-      throw new Error(`Type "${it.type}" is unsupported`);
+  const w = new Writer(ts);
+
+  function dispatch(it) {
+    if (it.type === "eof") {
+      return ts.trivia(it.trivia);
     }
-    return table[it.type](it, parent);
-  }
-  function iterate(things, parent) {
-    if (!things) return;
-    const results = things.map(thing => dispatch(thing, parent));
-    return ts.wrap(results);
+    return it.write(w);
   }
-  return iterate(ast);
+  return ts.wrap(ast.map(dispatch));
 }
 
 
 /***/ }),
 /* 31 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
+/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validate", function() { return validate; });
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "validate": () => (/* binding */ validate)
+/* harmony export */ });
 /* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
 
 
-
-
 function getMixinMap(all, unique) {
   const map = new Map();
-  const includes = all.filter(def => def.type === "includes");
+  const includes = all.filter((def) => def.type === "includes");
   for (const include of includes) {
     const mixin = unique.get(include.includes);
     if (!mixin) {
@@ -3178,7 +3598,7 @@ function groupDefinitions(all) {
     mixinMap: getMixinMap(all, unique),
     cache: {
       typedefIncludesDictionary: new WeakMap(),
-      dictionaryIncludesRequiredField: new WeakMap()
+      dictionaryIncludesRequiredField: new WeakMap(),
     },
   };
 }
@@ -3186,8 +3606,10 @@ function groupDefinitions(all) {
 function* checkDuplicatedNames({ unique, duplicates }) {
   for (const dup of duplicates) {
     const { name } = dup;
-    const message = `The name "${name}" of type "${unique.get(name).type}" was already seen`;
-    yield Object(_error_js__WEBPACK_IMPORTED_MODULE_0__["validationError"])(dup.tokens.name, dup, "no-duplicate", message);
+    const message = `The name "${name}" of type "${
+      unique.get(name).type
+    }" was already seen`;
+    yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(dup.tokens.name, dup, "no-duplicate", message);
   }
 }
 
@@ -3218,6 +3640,85 @@ function validate(ast) {
 
 
 /***/ })
-/******/ ]);
+/******/ 	]);
+/************************************************************************/
+/******/ 	// The module cache
+/******/ 	var __webpack_module_cache__ = {};
+/******/ 	
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/ 		// Check if module is in cache
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = __webpack_module_cache__[moduleId] = {
+/******/ 			// no module.id needed
+/******/ 			// no module.loaded needed
+/******/ 			exports: {}
+/******/ 		};
+/******/ 	
+/******/ 		// Execute the module function
+/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/ 	
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/ 	
+/************************************************************************/
+/******/ 	/* webpack/runtime/define property getters */
+/******/ 	(() => {
+/******/ 		// define getter functions for harmony exports
+/******/ 		__webpack_require__.d = (exports, definition) => {
+/******/ 			for(var key in definition) {
+/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ 				}
+/******/ 			}
+/******/ 		};
+/******/ 	})();
+/******/ 	
+/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
+/******/ 	(() => {
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
+/******/ 	})();
+/******/ 	
+/******/ 	/* webpack/runtime/make namespace object */
+/******/ 	(() => {
+/******/ 		// define __esModule on exports
+/******/ 		__webpack_require__.r = (exports) => {
+/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 			}
+/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 		};
+/******/ 	})();
+/******/ 	
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+(() => {
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   "parse": () => (/* reexport safe */ _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__.parse),
+/* harmony export */   "write": () => (/* reexport safe */ _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__.write),
+/* harmony export */   "validate": () => (/* reexport safe */ _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__.validate),
+/* harmony export */   "WebIDLParseError": () => (/* reexport safe */ _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__.WebIDLParseError)
+/* harmony export */ });
+/* harmony import */ var _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
+/* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);
+/* harmony import */ var _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31);
+/* harmony import */ var _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
+
+
+
+
+
+})();
+
+/******/ 	return __webpack_exports__;
+/******/ })()
+;
 });
 //# sourceMappingURL=webidl2.js.map
\ No newline at end of file
diff --git a/test/fixtures/wpt/user-timing/META.yml b/test/fixtures/wpt/user-timing/META.yml
new file mode 100644
index 00000000000000..5cb2a789c09c89
--- /dev/null
+++ b/test/fixtures/wpt/user-timing/META.yml
@@ -0,0 +1,4 @@
+spec: https://w3c.github.io/user-timing/
+suggested_reviewers:
+  - plehegar
+  - igrigorik
diff --git a/test/fixtures/wpt/user-timing/buffered-flag.any.js b/test/fixtures/wpt/user-timing/buffered-flag.any.js
new file mode 100644
index 00000000000000..f938c8522d829a
--- /dev/null
+++ b/test/fixtures/wpt/user-timing/buffered-flag.any.js
@@ -0,0 +1,27 @@
+async_test(t => {
+  // First observer creates second in callback to ensure the entry has been dispatched by the time
+  // the second observer begins observing.
+  new PerformanceObserver(() => {
+    // Second observer requires 'buffered: true' to see an entry.
+    new PerformanceObserver(t.step_func_done(list => {
+      const entries = list.getEntries();
+      assert_equals(entries.length, 1, 'There should be 1 mark entry.');
+      assert_equals(entries[0].entryType, 'mark');
+    })).observe({type: 'mark', buffered: true});
+  }).observe({entryTypes: ['mark']});
+  performance.mark('foo');
+}, 'PerformanceObserver with buffered flag sees previous marks');
+
+async_test(t => {
+  // First observer creates second in callback to ensure the entry has been dispatched by the time
+  // the second observer begins observing.
+  new PerformanceObserver(() => {
+    // Second observer requires 'buffered: true' to see an entry.
+    new PerformanceObserver(t.step_func_done(list => {
+      const entries = list.getEntries();
+      assert_equals(entries.length, 1, 'There should be 1 measure entry.');
+      assert_equals(entries[0].entryType, 'measure');
+    })).observe({type: 'measure', buffered: true});
+  }).observe({entryTypes: ['measure']});
+  performance.measure('bar');
+}, 'PerformanceObserver with buffered flag sees previous measures');
diff --git a/test/fixtures/wpt/user-timing/case-sensitivity.any.js b/test/fixtures/wpt/user-timing/case-sensitivity.any.js
new file mode 100644
index 00000000000000..1c0b0dcac361fe
--- /dev/null
+++ b/test/fixtures/wpt/user-timing/case-sensitivity.any.js
@@ -0,0 +1,25 @@
+  test(function () {
+    assert_equals(typeof self.performance, "object");
+    assert_equals(typeof self.performance.getEntriesByType, "function");
+
+    self.performance.mark("mark1");
+    self.performance.measure("measure1");
+
+    const type = [
+      'mark',
+      'measure',
+    ];
+    type.forEach(function(entryType) {
+      if (PerformanceObserver.supportedEntryTypes.includes(entryType)) {
+        const entryTypeUpperCased = entryType.toUpperCase();
+        const entryTypeCapitalized = entryType[0].toUpperCase() + entryType.substring(1);
+        const lowerList = self.performance.getEntriesByType(entryType);
+        const upperList = self.performance.getEntriesByType(entryTypeUpperCased);
+        const mixedList = self.performance.getEntriesByType(entryTypeCapitalized);
+
+        assert_greater_than(lowerList.length, 0, "Entries exist");
+        assert_equals(upperList.length, 0, "getEntriesByType('" + entryTypeCapitalized + "').length");
+        assert_equals(mixedList.length, 0, "getEntriesByType('" + entryTypeCapitalized + "').length");
+      }
+    });
+  }, "getEntriesByType values are case sensitive");
diff --git a/test/fixtures/wpt/user-timing/clearMarks.html b/test/fixtures/wpt/user-timing/clearMarks.html
new file mode 100644
index 00000000000000..92c60a3bbb856b
--- /dev/null
+++ b/test/fixtures/wpt/user-timing/clearMarks.html
@@ -0,0 +1,84 @@
+
+
+
+
+functionality test of window.performance.clearMarks
+
+
+
+
+
+
+
+
+
+
+    

Description

+

This test validates functionality of the interface window.performance.clearMarks.

+
+ + diff --git a/test/fixtures/wpt/user-timing/clearMeasures.html b/test/fixtures/wpt/user-timing/clearMeasures.html new file mode 100644 index 00000000000000..54d41005698305 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clearMeasures.html @@ -0,0 +1,77 @@ + + + + +functionality test of window.performance.clearMeasures + + + + + + + + + + +

Description

+

This test validates functionality of the interface window.performance.clearMeasures.

+
+ + diff --git a/test/fixtures/wpt/user-timing/clear_all_marks.any.js b/test/fixtures/wpt/user-timing/clear_all_marks.any.js new file mode 100644 index 00000000000000..35cd2a04f61036 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_all_marks.any.js @@ -0,0 +1,17 @@ +test(function() { + self.performance.mark("mark1"); + self.performance.mark("mark2"); + + // test that two marks have been created + var entries = self.performance.getEntriesByType("mark"); + assert_equals(entries.length, 2, "Two marks have been created for this test."); + + // clear all marks + self.performance.clearMarks(); + + // test that all marks were cleared + entries = self.performance.getEntriesByType("mark"); + + assert_equals(entries.length, 0, "All marks have been cleared."); + +}, "Clearing all marks remove all of them."); diff --git a/test/fixtures/wpt/user-timing/clear_all_measures.any.js b/test/fixtures/wpt/user-timing/clear_all_measures.any.js new file mode 100644 index 00000000000000..32c993f2827a30 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_all_measures.any.js @@ -0,0 +1,21 @@ +test(function() +{ + self.performance.mark("mark1"); + self.performance.measure("measure1", "mark1"); + self.performance.mark("mark2"); + self.performance.measure("measure2", "mark2"); + + // test that two measures have been created + var entries = self.performance.getEntriesByType("measure"); + assert_equals(entries.length, 2, "Two measures have been created for this test."); + + // clear all measures + self.performance.clearMeasures(); + + // test that all measures were cleared + entries = self.performance.getEntriesByType("measure"); + assert_equals(entries.length, 0, + "After a call to self.performance.clearMeasures(), " + + "self.performance.getEntriesByType(\"measure\") returns an empty object."); + +}, "Clearing all marks remove all of them."); diff --git a/test/fixtures/wpt/user-timing/clear_non_existent_mark.any.js b/test/fixtures/wpt/user-timing/clear_non_existent_mark.any.js new file mode 100644 index 00000000000000..c7d8b478613401 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_non_existent_mark.any.js @@ -0,0 +1,26 @@ +test(function() { + self.performance.mark("mark1"); + self.performance.mark("mark2"); + + // test that two marks have been created + var entries = self.performance.getEntriesByType("mark"); + assert_equals(entries.length, 2, "Two marks have been created for this test."); + + // clear non-existent mark + self.performance.clearMarks("mark3"); + + // test that "mark1" still exists + entries = self.performance.getEntriesByName("mark1"); + assert_equals(entries[0].name, "mark1", + "After a call to self.performance.clearMarks(\"mark3\"), where \"mark3" + + "\" is a non-existent mark, self.performance.getEntriesByName(\"mark1\") " + + "returns an object containing the \"mark1\" mark."); + + // test that "mark2" still exists + entries = self.performance.getEntriesByName("mark2"); + assert_equals(entries[0].name, "mark2", + "After a call to self.performance.clearMarks(\"mark3\"), where \"mark3" + + "\" is a non-existent mark, self.performance.getEntriesByName(\"mark2\") " + + "returns an object containing the \"mark2\" mark."); + +}, "Clearing a non-existent mark doesn't affect existing marks"); diff --git a/test/fixtures/wpt/user-timing/clear_non_existent_measure.any.js b/test/fixtures/wpt/user-timing/clear_non_existent_measure.any.js new file mode 100644 index 00000000000000..9de0b5f266d4e2 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_non_existent_measure.any.js @@ -0,0 +1,29 @@ +test(function() +{ + self.performance.mark("mark1"); + self.performance.measure("measure1", "mark1"); + self.performance.mark("mark2"); + self.performance.measure("measure2", "mark2"); + + // test that two measures have been created + var entries = self.performance.getEntriesByType("measure"); + assert_equals(entries.length, 2, "Two measures have been created for this test."); + + // clear non-existent measure + self.performance.clearMeasures("measure3"); + + // test that "measure1" still exists + entries = self.performance.getEntriesByName("measure1"); + assert_equals(entries[0].name, "measure1", + "After a call to self.performance.clearMeasures(\"measure3\"), where \"measure3" + + "\" is a non-existent measure, self.performance.getEntriesByName(\"measure1\") " + + "returns an object containing the \"measure1\" measure."); + + // test that "measure2" still exists + entries = self.performance.getEntriesByName("measure2"); + assert_equals(entries[0].name, "measure2", + "After a call to self.performance.clearMeasures(\"measure3\"), where \"measure3" + + "\" is a non-existent measure, self.performance.getEntriesByName(\"measure2\") " + + "returns an object containing the \"measure2\" measure."); + +}, "Clearing a non-existent measure doesn't affect existing measures"); diff --git a/test/fixtures/wpt/user-timing/clear_one_mark.any.js b/test/fixtures/wpt/user-timing/clear_one_mark.any.js new file mode 100644 index 00000000000000..c180199d8c9f92 --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_one_mark.any.js @@ -0,0 +1,26 @@ +test(function() { + self.performance.mark("mark1"); + self.performance.mark("mark2"); + + // test that two marks have been created + var entries = self.performance.getEntriesByType("mark"); + assert_equals(entries.length, 2, "Two marks have been created for this test."); + + // clear existent mark + self.performance.clearMarks("mark1"); + + // test that "mark1" was cleared + entries = self.performance.getEntriesByName("mark1"); + + assert_equals(entries.length, 0, + "After a call to self.performance.clearMarks(\"mark1\"), " + + "window.performance.getEntriesByName(\"mark1\") returns an empty object."); + + // test that "mark2" still exists + entries = self.performance.getEntriesByName("mark2"); + assert_equals(entries[0].name, "mark2", + "After a call to self.performance.clearMarks(\"mark1\"), " + + "window.performance.getEntriesByName(\"mark2\") returns an object containing the " + + "\"mark2\" mark."); + +}, "Clearing an existent mark doesn't affect other existing marks"); diff --git a/test/fixtures/wpt/user-timing/clear_one_measure.any.js b/test/fixtures/wpt/user-timing/clear_one_measure.any.js new file mode 100644 index 00000000000000..a5e663772c8bbe --- /dev/null +++ b/test/fixtures/wpt/user-timing/clear_one_measure.any.js @@ -0,0 +1,29 @@ +test(function() +{ + self.performance.mark("mark1"); + self.performance.measure("measure1", "mark1"); + self.performance.mark("mark2"); + self.performance.measure("measure2", "mark2"); + + // test that two measures have been created + var entries = self.performance.getEntriesByType("measure"); + assert_equals(entries.length, 2, "Two measures have been created for this test."); + + // clear existent measure + self.performance.clearMeasures("measure1"); + + // test that "measure1" was cleared + entries = self.performance.getEntriesByName("measure1"); + + assert_equals(entries.length, 0, + "After a call to self.performance.clearMeasures(\"measure1\"), " + + "self.performance.getEntriesByName(\"measure1\") returns an empty object."); + + // test that "measure2" still exists + entries = self.performance.getEntriesByName("measure2"); + assert_equals(entries[0].name, "measure2", + "After a call to self.performance.clearMeasures(\"measure1\"), " + + "self.performance.getEntriesByName(\"measure2\") returns an object containing the " + + "\"measure2\" measure."); + +}, "Clearing an existent measure doesn't affect other existing measures"); diff --git a/test/fixtures/wpt/user-timing/entry_type.any.js b/test/fixtures/wpt/user-timing/entry_type.any.js new file mode 100644 index 00000000000000..1e37453d09d42e --- /dev/null +++ b/test/fixtures/wpt/user-timing/entry_type.any.js @@ -0,0 +1,13 @@ +test(function () { + self.performance.mark('mark'); + var mark_entry = self.performance.getEntriesByName('mark')[0]; + + assert_equals(Object.prototype.toString.call(mark_entry), '[object PerformanceMark]', 'Class name of mark entry should be PerformanceMark.'); +}, "Validate the user timing entry type PerformanceMark"); + +test(function () { + self.performance.measure('measure'); + var measure_entry = self.performance.getEntriesByName('measure')[0]; + + assert_equals(Object.prototype.toString.call(measure_entry), '[object PerformanceMeasure]', 'Class name of measure entry should be PerformanceMeasure.'); +}, "Validate the user timing entry type PerformanceMeasure"); diff --git a/test/fixtures/wpt/user-timing/idlharness.any.js b/test/fixtures/wpt/user-timing/idlharness.any.js new file mode 100644 index 00000000000000..511f2d0455b833 --- /dev/null +++ b/test/fixtures/wpt/user-timing/idlharness.any.js @@ -0,0 +1,33 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: timeout=long + +// https://w3c.github.io/user-timing/ + +'use strict'; + +idl_test( + ['user-timing'], + ['hr-time', 'performance-timeline', 'dom'], + idl_array => { + try { + performance.mark('test'); + performance.measure('test'); + for (const m of performance.getEntriesByType('mark')) { + self.mark = m; + } + for (const m of performance.getEntriesByType('measure')) { + self.measure = m; + } + } catch (e) { + // Will be surfaced when mark is undefined below. + } + + idl_array.add_objects({ + Performance: ['performance'], + PerformanceMark: ['mark'], + PerformanceMeasure: ['measure'], + }); + } +); diff --git a/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.html b/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.html new file mode 100644 index 00000000000000..1df94a3006d7fb --- /dev/null +++ b/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.html @@ -0,0 +1,35 @@ + + + + + exception test of performance.mark and performance.measure + + + + + + +

Description

+

This test validates exception scenarios of invoking mark() and measure() with timing attributes as value.

+
+ + + diff --git a/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.worker.js b/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.worker.js new file mode 100644 index 00000000000000..32677c64d3bd5f --- /dev/null +++ b/test/fixtures/wpt/user-timing/invoke_with_timing_attributes.worker.js @@ -0,0 +1,25 @@ +importScripts("/resources/testharness.js"); +importScripts("resources/webperftestharness.js"); + +function emit_test(attrName) { + test(function() { + performance.mark(attrName); + performance.clearMarks(attrName); + }, "performance.mark should not throw if used with timing attribute " + attrName + + " in workers"); +} +for (var i in timingAttributes) { + emit_test(timingAttributes[i]); +} + +function emit_test2(attrName) { + test(function() { + performance.measure(attrName); + performance.clearMeasures(attrName); + }, "performance.measure should not throw if used with timing attribute " + attrName + + " in workers"); +} +for (var i in timingAttributes) { + emit_test2(timingAttributes[i]); +} +done(); diff --git a/test/fixtures/wpt/user-timing/invoke_without_parameter.html b/test/fixtures/wpt/user-timing/invoke_without_parameter.html new file mode 100644 index 00000000000000..114435e59befbb --- /dev/null +++ b/test/fixtures/wpt/user-timing/invoke_without_parameter.html @@ -0,0 +1,26 @@ + + + + + exception test of performance.mark and performance.measure + + + + + + + +

Description

+

This test validates exception scenarios of invoking mark() and measure() without parameter.

+
+ + + diff --git a/test/fixtures/wpt/user-timing/mark-entry-constructor.any.js b/test/fixtures/wpt/user-timing/mark-entry-constructor.any.js new file mode 100644 index 00000000000000..ef9c403dda6723 --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark-entry-constructor.any.js @@ -0,0 +1,40 @@ +// META: script=resources/user-timing-helper.js + +test(()=>{ + const entry = new PerformanceMark("name"); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark"}); +}, "Mark entry can be created by 'new PerformanceMark(string)'."); + +test(()=>{ + const entry = new PerformanceMark("name", {}); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark"}); +}, "Mark entry can be created by 'new PerformanceMark(string, {})'."); + +test(()=>{ + const entry = new PerformanceMark("name", {startTime: 1}); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark", startTime: 1}); +}, "Mark entry can be created by 'new PerformanceMark(string, {startTime})'."); + +test(()=>{ + const entry = new PerformanceMark("name", {detail: {info: "abc"}}); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark", detail: {info: "abc"}}); +}, "Mark entry can be created by 'new PerformanceMark(string, {detail})'."); + +test(()=>{ + const entry = + new PerformanceMark("name", {startTime: 1, detail: {info: "abc"}}); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark", startTime: 1, detail: {info: "abc"}}); +}, "Mark entry can be created by " + + "'new PerformanceMark(string, {startTime, detail})'."); + +test(()=>{ + const entry = new PerformanceMark("name"); + assert_true(entry instanceof PerformanceMark); + checkEntry(entry, {name: "name", entryType: "mark"}); + assert_equals(performance.getEntriesByName("name").length, 0); +}, "Using new PerformanceMark() shouldn't add the entry to performance timeline."); diff --git a/test/fixtures/wpt/user-timing/mark-errors.any.js b/test/fixtures/wpt/user-timing/mark-errors.any.js new file mode 100644 index 00000000000000..dcd36695e22f2c --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark-errors.any.js @@ -0,0 +1,15 @@ +test(function() { + assert_throws_js(TypeError, function() { self.performance.mark("mark1", 123); }, "Number passed as a dict argument should cause type-error.") +}, "Number should be rejected as the mark-options.") + +test(function() { + assert_throws_js(TypeError, function() { self.performance.mark("mark1", NaN); }, "NaN passed as a dict argument should cause type-error.") +}, "NaN should be rejected as the mark-options.") + +test(function() { + assert_throws_js(TypeError, function() { self.performance.mark("mark1", Infinity); }, "Infinity passed as a dict argument should cause type-error.") +}, "Infinity should be rejected as the mark-options.") + +test(function() { + assert_throws_js(TypeError, function() { self.performance.mark("mark1", "string"); }, "String passed as a dict argument should cause type-error.") +}, "String should be rejected as the mark-options.") diff --git a/test/fixtures/wpt/user-timing/mark-l3.any.js b/test/fixtures/wpt/user-timing/mark-l3.any.js new file mode 100644 index 00000000000000..407a5c8bba6a3c --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark-l3.any.js @@ -0,0 +1,39 @@ +// META: script=resources/user-timing-helper.js + +async_test(function (t) { + let mark_entries = []; + const expected_entries = + [{ entryType: "mark", name: "mark1", detail: null}, + { entryType: "mark", name: "mark2", detail: null}, + { entryType: "mark", name: "mark3", detail: null}, + { entryType: "mark", name: "mark4", detail: null}, + { entryType: "mark", name: "mark5", detail: null}, + { entryType: "mark", name: "mark6", detail: {}}, + { entryType: "mark", name: "mark7", detail: {info: 'abc'}}, + { entryType: "mark", name: "mark8", detail: null, startTime: 234.56}, + { entryType: "mark", name: "mark9", detail: {count: 3}, startTime: 345.67}]; + const observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + mark_entries = + mark_entries.concat(entryList.getEntries()); + if (mark_entries.length >= expected_entries.length) { + checkEntries(mark_entries, expected_entries); + observer.disconnect(); + t.done(); + } + }) + ); + self.performance.clearMarks(); + observer.observe({entryTypes: ["mark"]}); + const returned_entries = []; + returned_entries.push(self.performance.mark("mark1")); + returned_entries.push(self.performance.mark("mark2", undefined)); + returned_entries.push(self.performance.mark("mark3", null)); + returned_entries.push(self.performance.mark("mark4", {})); + returned_entries.push(self.performance.mark("mark5", {detail: null})); + returned_entries.push(self.performance.mark("mark6", {detail: {}})); + returned_entries.push(self.performance.mark("mark7", {detail: {info: 'abc'}})); + returned_entries.push(self.performance.mark("mark8", {startTime: 234.56})); + returned_entries.push(self.performance.mark("mark9", {detail: {count: 3}, startTime: 345.67})); + checkEntries(returned_entries, expected_entries); +}, "mark entries' detail and startTime are customizable."); diff --git a/test/fixtures/wpt/user-timing/mark-measure-feature-detection.html b/test/fixtures/wpt/user-timing/mark-measure-feature-detection.html new file mode 100644 index 00000000000000..6f1ad489e95680 --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark-measure-feature-detection.html @@ -0,0 +1,36 @@ + + +User Timing: L2 vs L3 feature detection + + + diff --git a/test/fixtures/wpt/user-timing/mark-measure-return-objects.any.js b/test/fixtures/wpt/user-timing/mark-measure-return-objects.any.js new file mode 100644 index 00000000000000..bb15c5839818ba --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark-measure-return-objects.any.js @@ -0,0 +1,37 @@ +async_test(function (t) { + self.performance.clearMeasures(); + const measure = self.performance.measure("measure1"); + assert_true(measure instanceof PerformanceMeasure); + t.done(); +}, "L3: performance.measure(name) should return an entry."); + +async_test(function (t) { + self.performance.clearMeasures(); + const measure = self.performance.measure("measure2", + { start: 12, end: 23 }); + assert_true(measure instanceof PerformanceMeasure); + t.done(); +}, "L3: performance.measure(name, param1) should return an entry."); + +async_test(function (t) { + self.performance.clearMeasures(); + self.performance.mark("1"); + self.performance.mark("2"); + const measure = self.performance.measure("measure3", "1", "2"); + assert_true(measure instanceof PerformanceMeasure); + t.done(); +}, "L3: performance.measure(name, param1, param2) should return an entry."); + +async_test(function (t) { + self.performance.clearMarks(); + const mark = self.performance.mark("mark1"); + assert_true(mark instanceof PerformanceMark); + t.done(); +}, "L3: performance.mark(name) should return an entry."); + +async_test(function (t) { + self.performance.clearMarks(); + const mark = self.performance.mark("mark2", { startTime: 34 }); + assert_true(mark instanceof PerformanceMark); + t.done(); +}, "L3: performance.mark(name, param) should return an entry."); diff --git a/test/fixtures/wpt/user-timing/mark.any.js b/test/fixtures/wpt/user-timing/mark.any.js new file mode 100644 index 00000000000000..7e814d2074ca8b --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark.any.js @@ -0,0 +1,118 @@ +// test data +var testThreshold = 20; + +var expectedTimes = new Array(); + +function match_entries(entries, index) +{ + var entry = entries[index]; + var match = self.performance.getEntriesByName("mark")[index]; + assert_equals(entry.name, match.name, "entry.name"); + assert_equals(entry.startTime, match.startTime, "entry.startTime"); + assert_equals(entry.entryType, match.entryType, "entry.entryType"); + assert_equals(entry.duration, match.duration, "entry.duration"); +} + +function filter_entries_by_type(entryList, entryType) +{ + var testEntries = new Array(); + + // filter entryList + for (var i in entryList) + { + if (entryList[i].entryType == entryType) + { + testEntries.push(entryList[i]); + } + } + + return testEntries; +} + +test(function () { + // create first mark + self.performance.mark("mark"); + + expectedTimes[0] = self.performance.now(); + + const entries = self.performance.getEntriesByName("mark"); + assert_equals(entries.length, 1); +}, "Entry 0 is properly created"); + +test(function () { + // create second, duplicate mark + self.performance.mark("mark"); + + expectedTimes[1] = self.performance.now(); + + const entries = self.performance.getEntriesByName("mark"); + assert_equals(entries.length, 2); + +}, "Entry 1 is properly created"); + +function test_mark(index) { + test(function () { + const entries = self.performance.getEntriesByName("mark"); + assert_equals(entries[index].name, "mark", "Entry has the proper name"); + }, "Entry " + index + " has the proper name"); + + test(function () { + const entries = self.performance.getEntriesByName("mark"); + assert_approx_equals(entries[index].startTime, expectedTimes[index], testThreshold); + }, "Entry " + index + " startTime is approximately correct (up to " + testThreshold + + "ms difference allowed)"); + + test(function () { + const entries = self.performance.getEntriesByName("mark"); + assert_equals(entries[index].entryType, "mark"); + }, "Entry " + index + " has the proper entryType"); + + test(function () { + const entries = self.performance.getEntriesByName("mark"); + assert_equals(entries[index].duration, 0); + }, "Entry " + index + " duration == 0"); + + test(function () { + const entries = self.performance.getEntriesByName("mark", "mark"); + assert_equals(entries[index].name, "mark"); + }, "getEntriesByName(\"mark\", \"mark\")[" + index + "] returns an " + + "object containing a \"mark\" mark"); + + test(function () { + const entries = self.performance.getEntriesByName("mark", "mark"); + match_entries(entries, index); + }, "The mark returned by getEntriesByName(\"mark\", \"mark\")[" + index + + "] matches the mark returned by " + + "getEntriesByName(\"mark\")[" + index + "]"); + + test(function () { + const entries = filter_entries_by_type(self.performance.getEntries(), "mark"); + assert_equals(entries[index].name, "mark"); + }, "getEntries()[" + index + "] returns an " + + "object containing a \"mark\" mark"); + + test(function () { + const entries = filter_entries_by_type(self.performance.getEntries(), "mark"); + match_entries(entries, index); + }, "The mark returned by getEntries()[" + index + + "] matches the mark returned by " + + "getEntriesByName(\"mark\")[" + index + "]"); + + test(function () { + const entries = self.performance.getEntriesByType("mark"); + assert_equals(entries[index].name, "mark"); + }, "getEntriesByType(\"mark\")[" + index + "] returns an " + + "object containing a \"mark\" mark"); + + test(function () { + const entries = self.performance.getEntriesByType("mark"); + match_entries(entries, index); + }, "The mark returned by getEntriesByType(\"mark\")[" + index + + "] matches the mark returned by " + + "getEntriesByName(\"mark\")[" + index + "]"); + +} + +for (var i = 0; i < expectedTimes.length; i++) { + test_mark(i); +} diff --git a/test/fixtures/wpt/user-timing/mark.html b/test/fixtures/wpt/user-timing/mark.html new file mode 100644 index 00000000000000..e03e9e6247adab --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark.html @@ -0,0 +1,58 @@ + + + + +functionality test of window.performance.mark + + + + + + + + + + +

Description

+

This test validates functionality of the interface window.performance.mark.

+
+ + diff --git a/test/fixtures/wpt/user-timing/mark_exceptions.html b/test/fixtures/wpt/user-timing/mark_exceptions.html new file mode 100644 index 00000000000000..b445c6b8778ae7 --- /dev/null +++ b/test/fixtures/wpt/user-timing/mark_exceptions.html @@ -0,0 +1,41 @@ + + + + + window.performance User Timing mark() method is throwing the proper exceptions + + + + + + + + + +

Description

+

This test validates that the performance.mark() method throws a SYNTAX_ERR exception whenever a navigation + timing attribute is provided for the name parameter. +

+ +
+ + diff --git a/test/fixtures/wpt/user-timing/measure-exceptions.html b/test/fixtures/wpt/user-timing/measure-exceptions.html new file mode 100644 index 00000000000000..2836eaee2a86c1 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure-exceptions.html @@ -0,0 +1,49 @@ + + + + This tests that 'performance.measure' throws exceptions with reasonable messages. + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/user-timing/measure-l3.any.js b/test/fixtures/wpt/user-timing/measure-l3.any.js new file mode 100644 index 00000000000000..24c27c483515ed --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure-l3.any.js @@ -0,0 +1,35 @@ +// META: script=resources/user-timing-helper.js + +function endTime(entry) { + return entry.startTime + entry.duration; +} + +test(function() { + performance.clearMarks(); + performance.clearMeasures(); + const markEntry = performance.mark("mark", {startTime: 123}); + const measureEntry = performance.measure("A", undefined, "mark"); + assert_equals(measureEntry.startTime, 0); + assert_equals(endTime(measureEntry), markEntry.startTime); +}, "When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0."); + +test(function() { + performance.clearMarks(); + performance.clearMeasures(); + const markEntry = performance.mark("mark", {startTime: 123}); + const endMin = performance.now(); + const measureEntry = performance.measure("A", "mark", undefined); + const endMax = performance.now(); + assert_equals(measureEntry.startTime, markEntry.startTime); + assert_greater_than_equal(endTime(measureEntry), endMin); + assert_greater_than_equal(endMax, endTime(measureEntry)); +}, "When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now."); + +test(function() { + performance.clearMarks(); + performance.clearMeasures(); + const markEntry = performance.mark("mark", {startTime: 123}); + const measureEntry = performance.measure("A", "mark", "mark"); + assert_equals(endTime(measureEntry), markEntry.startTime); + assert_equals(measureEntry.startTime, markEntry.startTime); +}, "When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively"); diff --git a/test/fixtures/wpt/user-timing/measure-with-dict.any.js b/test/fixtures/wpt/user-timing/measure-with-dict.any.js new file mode 100644 index 00000000000000..b452feb0de6fbb --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure-with-dict.any.js @@ -0,0 +1,112 @@ +// META: script=resources/user-timing-helper.js + +function cleanupPerformanceTimeline() { + performance.clearMarks(); + performance.clearMeasures(); +} + +async_test(function (t) { + this.add_cleanup(cleanupPerformanceTimeline); + let measureEntries = []; + const timeStamp1 = 784.4; + const timeStamp2 = 1234.5; + const timeStamp3 = 66.6; + const timeStamp4 = 5566; + const expectedEntries = + [{ entryType: "measure", name: "measure1", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure2", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure3", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure4", detail: null }, + { entryType: "measure", name: "measure5", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure6", detail: null, startTime: timeStamp1 }, + { entryType: "measure", name: "measure7", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 }, + { entryType: "measure", name: "measure8", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure9", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure10", detail: null, startTime: timeStamp1 }, + { entryType: "measure", name: "measure11", detail: null, startTime: timeStamp3 }, + { entryType: "measure", name: "measure12", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure13", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure14", detail: null, startTime: timeStamp3, duration: timeStamp1 - timeStamp3 }, + { entryType: "measure", name: "measure15", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 }, + { entryType: "measure", name: "measure16", detail: null, startTime: timeStamp1 }, + { entryType: "measure", name: "measure17", detail: { customInfo: 159 }, startTime: timeStamp3, duration: timeStamp2 - timeStamp3 }, + { entryType: "measure", name: "measure18", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 }, + { entryType: "measure", name: "measure19", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 }, + { entryType: "measure", name: "measure20", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure21", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure22", detail: null, startTime: 0 }, + { entryType: "measure", name: "measure23", detail: null, startTime: 0 }]; + const observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + measureEntries = + measureEntries.concat(entryList.getEntries()); + if (measureEntries.length >= expectedEntries.length) { + checkEntries(measureEntries, expectedEntries); + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({ entryTypes: ["measure"] }); + self.performance.mark("mark1", { detail: { randomInfo: 3 }, startTime: timeStamp1 }); + self.performance.mark("mark2", { startTime: timeStamp2 }); + + const returnedEntries = []; + returnedEntries.push(self.performance.measure("measure1")); + returnedEntries.push(self.performance.measure("measure2", undefined)); + returnedEntries.push(self.performance.measure("measure3", null)); + returnedEntries.push(self.performance.measure("measure4", 'mark1')); + returnedEntries.push( + self.performance.measure("measure5", null, 'mark1')); + returnedEntries.push( + self.performance.measure("measure6", 'mark1', undefined)); + returnedEntries.push( + self.performance.measure("measure7", 'mark1', 'mark2')); + returnedEntries.push( + self.performance.measure("measure8", {})); + returnedEntries.push( + self.performance.measure("measure9", { start: undefined })); + returnedEntries.push( + self.performance.measure("measure10", { start: 'mark1' })); + returnedEntries.push( + self.performance.measure("measure11", { start: timeStamp3 })); + returnedEntries.push( + self.performance.measure("measure12", { end: undefined })); + returnedEntries.push( + self.performance.measure("measure13", { end: 'mark1' })); + returnedEntries.push( + self.performance.measure("measure14", { start: timeStamp3, end: 'mark1' })); + returnedEntries.push( + self.performance.measure("measure15", { start: timeStamp1, end: timeStamp2, detail: undefined })); + returnedEntries.push( + self.performance.measure("measure16", { start: 'mark1', end: undefined, detail: null })); + returnedEntries.push( + self.performance.measure("measure17", { start: timeStamp3, end: 'mark2', detail: { customInfo: 159 }})); + returnedEntries.push( + self.performance.measure("measure18", { start: timeStamp1, duration: timeStamp2 - timeStamp1 })); + returnedEntries.push( + self.performance.measure("measure19", { duration: timeStamp2 - timeStamp1, end: timeStamp2 })); + // {}, null, undefined, invalid-dict passed to startOrOptions are interpreted as start time being 0. + returnedEntries.push(self.performance.measure("measure20", {}, 'mark1')); + returnedEntries.push(self.performance.measure("measure21", null, 'mark1')); + returnedEntries.push(self.performance.measure("measure22", undefined, 'mark1')); + returnedEntries.push(self.performance.measure("measure23", { invalidDict:1 }, 'mark1')); + checkEntries(returnedEntries, expectedEntries); +}, "measure entries' detail and start/end are customizable"); + +test(function() { + this.add_cleanup(cleanupPerformanceTimeline); + assert_throws_js(TypeError, function() { + self.performance.measure("optionsAndNumberEnd", {'start': 2}, 12); + }, "measure should throw a TypeError when passed an options object and an end time"); + assert_throws_js(TypeError, function() { + self.performance.measure("optionsAndMarkEnd", {'start': 2}, 'mark1'); + }, "measure should throw a TypeError when passed an options object and an end mark"); + assert_throws_js(TypeError, function() { + self.performance.measure("negativeStartInOptions", {'start': -1}); + }, "measure cannot have a negative time stamp."); + assert_throws_js(TypeError, function() { + self.performance.measure("negativeEndInOptions", {'end': -1}); + }, "measure cannot have a negative time stamp for end."); +}, "measure should throw a TypeError when passed an invalid argument combination"); + diff --git a/test/fixtures/wpt/user-timing/measure.html b/test/fixtures/wpt/user-timing/measure.html new file mode 100644 index 00000000000000..40f71a3362b581 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure.html @@ -0,0 +1,362 @@ + + + + + + window.performance User Timing measure() method is working properly + + + + + + + + + + +

Description

+

This test validates that the performance.measure() method is working properly. This test creates the + following measures to test this method: +

    +
  • "measure_no_start_no_end": created using a measure() call without a startMark or endMark + provided
  • +
  • "measure_start_no_end": created using a measure() call with only the startMark provided
  • +
  • "measure_start_end": created using a measure() call with both a startMark or endMark provided
  • +
  • "measure_no_start_end": created using a measure() call with only the endMark provided
  • +
  • "measure_no_start_no_end": duplicate of the first measure, used to confirm names can be re-used
  • +
+ After creating each measure, the existence of these measures is validated by calling + performance.getEntriesByName() (both with and without the entryType parameter provided), + performance.getEntriesByType(), and performance.getEntries() +

+ +
+ + diff --git a/test/fixtures/wpt/user-timing/measure_associated_with_navigation_timing.html b/test/fixtures/wpt/user-timing/measure_associated_with_navigation_timing.html new file mode 100644 index 00000000000000..702e3d5f87f39e --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure_associated_with_navigation_timing.html @@ -0,0 +1,57 @@ + + + + +functionality test of window.performance.measure + + + + + + + + + + +

Description

+

This test validates functionality of the interface window.performance.measure using keywords from the Navigation Timing spec.

+
+ + diff --git a/test/fixtures/wpt/user-timing/measure_exception.html b/test/fixtures/wpt/user-timing/measure_exception.html new file mode 100644 index 00000000000000..5c1aa086c0fc88 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure_exception.html @@ -0,0 +1,34 @@ + + + + +exception test of window.performance.measure + + + + + + + + + + +

Description

+

This test validates all exception scenarios of method window.performance.measure in User Timing API

+ +
+ + + diff --git a/test/fixtures/wpt/user-timing/measure_exceptions_navigation_timing.html b/test/fixtures/wpt/user-timing/measure_exceptions_navigation_timing.html new file mode 100644 index 00000000000000..b1868b2cb6b3cb --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure_exceptions_navigation_timing.html @@ -0,0 +1,70 @@ + + + + + window.performance User Timing measure() method is throwing the proper exceptions + + + + + + + + + +

Description

+

window.performance.measure() method throws a InvalidAccessError + whenever a navigation timing attribute with a value of zero is provided as the startMark or endMark. +

+ +
+ + diff --git a/test/fixtures/wpt/user-timing/measure_navigation_timing.html b/test/fixtures/wpt/user-timing/measure_navigation_timing.html new file mode 100644 index 00000000000000..d6480d27a261c9 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure_navigation_timing.html @@ -0,0 +1,205 @@ + + + + + + window.performance User Timing clearMeasures() method is working properly with navigation timing + attributes + + + + + + + + + + +

Description

+

This test validates that the performance.measure() method is working properly when navigation timing + attributes are used in place of mark names. This test creates the following measures to test this method: +

    +
  • "measure_nav_start_no_end": created using a measure() call with a navigation timing attribute + provided as the startMark and nothing provided as the endMark
  • +
  • "measure_nav_start_mark_end": created using a measure() call with a navigation timing attribute + provided as the startMark and a mark name provided as the endMark
  • +
  • "measure_mark_start_nav_end": created using a measure() call with a mark name provided as the + startMark and a navigation timing attribute provided as the endMark
  • +
  • "measure_nav_start_nav_end":created using a measure() call with a navigation timing attribute + provided as both the startMark and endMark
  • +
+ After creating each measure, the existence of these measures is validated by calling + performance.getEntriesByName() with each measure name +

+ +
+ + diff --git a/test/fixtures/wpt/user-timing/measure_syntax_err.any.js b/test/fixtures/wpt/user-timing/measure_syntax_err.any.js new file mode 100644 index 00000000000000..9b762a40906351 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measure_syntax_err.any.js @@ -0,0 +1,33 @@ +test(function () { + self.performance.mark("existing_mark"); + var entries = self.performance.getEntriesByName("existing_mark"); + assert_equals(entries.length, 1); + self.performance.measure("measure", "existing_mark"); +}, "Create a mark \"existing_mark\""); +test(function () { + assert_throws_dom("SyntaxError", function () { + self.performance.measure("measure", "mark"); + }); +}, "self.performance.measure(\"measure\", \"mark\"), where \"mark\" is a non-existent mark, " + + "throws a SyntaxError exception."); + +test(function () { + assert_throws_dom("SyntaxError", function () { + self.performance.measure("measure", "mark", "existing_mark"); + }); +}, "self.performance.measure(\"measure\", \"mark\", \"existing_mark\"), where \"mark\" is a " + + "non-existent mark, throws a SyntaxError exception."); + +test(function () { + assert_throws_dom("SyntaxError", function () { + self.performance.measure("measure", "existing_mark", "mark"); + }); +}, "self.performance.measure(\"measure\", \"existing_mark\", \"mark\"), where \"mark\" " + + "is a non-existent mark, throws a SyntaxError exception."); + +test(function () { + assert_throws_dom("SyntaxError", function () { + self.performance.measure("measure", "mark", "mark"); + }); +}, "self.performance.measure(\"measure\", \"mark\", \"mark\"), where \"mark\" is a " + + "non-existent mark, throws a SyntaxError exception."); diff --git a/test/fixtures/wpt/user-timing/measures.html b/test/fixtures/wpt/user-timing/measures.html new file mode 100644 index 00000000000000..0de68965ddb9c7 --- /dev/null +++ b/test/fixtures/wpt/user-timing/measures.html @@ -0,0 +1,66 @@ + + + + +functionality test of window.performance.measure + + + + + + + + + + +

Description

+

This test validates functionality of the interface window.performance.measure.

+
+ + diff --git a/test/fixtures/wpt/user-timing/performance-measure-invalid.worker.js b/test/fixtures/wpt/user-timing/performance-measure-invalid.worker.js new file mode 100644 index 00000000000000..29efb729992cc6 --- /dev/null +++ b/test/fixtures/wpt/user-timing/performance-measure-invalid.worker.js @@ -0,0 +1,9 @@ +importScripts("/resources/testharness.js"); + +test(() => { + assert_throws_js(TypeError, () => { + performance.measure('name', 'navigationStart', 'navigationStart'); + }); +}, "When converting 'navigationStart' to a timestamp, the global object has to be a Window object."); + +done(); diff --git a/test/fixtures/wpt/user-timing/resources/user-timing-helper.js b/test/fixtures/wpt/user-timing/resources/user-timing-helper.js new file mode 100644 index 00000000000000..8d43768ec28196 --- /dev/null +++ b/test/fixtures/wpt/user-timing/resources/user-timing-helper.js @@ -0,0 +1,30 @@ +// Compares a list of performance entries to a predefined one. +// actualEntries is an array of performance entries from the user agent, +// and expectedEntries is an array of performance entries minted by the test. +// The comparison doesn't assert the order of the entries. +function checkEntries(actualEntries, expectedEntries) { + assert_equals(actualEntries.length, expectedEntries.length, + `The length of actual and expected entries should match. + actual: ${JSON.stringify(actualEntries)}, + expected: ${JSON.stringify(expectedEntries)}`); + const actualEntrySet = new Set(actualEntries.map(ae=>ae.name)); + assert_equals(actualEntrySet.size, actualEntries.length, `Actual entry names are not unique: ${JSON.stringify(actualEntries)}`); + const expectedEntrySet = new Set(expectedEntries.map(ee=>ee.name)); + assert_equals(expectedEntrySet.size, expectedEntries.length, `Expected entry names are not unique: ${JSON.stringify(expectedEntries)}`); + actualEntries.forEach(ae=>{ + const expectedEntry = expectedEntries.find(e=>e.name === ae.name); + assert_true(!!expectedEntry, `Entry name '${ae.name}' was not found.`); + checkEntry(ae, expectedEntry); + }); +} + +function checkEntry(entry, {name, entryType, startTime, detail, duration}) { + assert_equals(entry.name, name); + assert_equals(entry.entryType, entryType); + if (startTime !== undefined) + assert_equals(entry.startTime, startTime); + if (detail !== undefined) + assert_equals(JSON.stringify(entry.detail), JSON.stringify(detail)); + if (duration !== undefined) + assert_equals(entry.duration, duration); +} diff --git a/test/fixtures/wpt/user-timing/resources/webperftestharness.js b/test/fixtures/wpt/user-timing/resources/webperftestharness.js new file mode 100644 index 00000000000000..2fbd0210de906d --- /dev/null +++ b/test/fixtures/wpt/user-timing/resources/webperftestharness.js @@ -0,0 +1,124 @@ +// +// Helper functions for User Timing tests +// + +var timingAttributes = [ + "navigationStart", + "unloadEventStart", + "unloadEventEnd", + "redirectStart", + "redirectEnd", + "fetchStart", + "domainLookupStart", + "domainLookupEnd", + "connectStart", + "connectEnd", + "secureConnectionStart", + "requestStart", + "responseStart", + "responseEnd", + "domLoading", + "domInteractive", + "domContentLoadedEventStart", + "domContentLoadedEventEnd", + "domComplete", + "loadEventStart", + "loadEventEnd" +]; + +function has_required_interfaces() +{ + if (window.performance.mark == undefined || + window.performance.clearMarks == undefined || + window.performance.measure == undefined || + window.performance.clearMeasures == undefined || + window.performance.getEntriesByName == undefined || + window.performance.getEntriesByType == undefined || + window.performance.getEntries == undefined) { + return false; + } + + return true; +} + +function test_namespace(child_name, skip_root) +{ + if (skip_root === undefined) { + var msg = 'window.performance is defined'; + wp_test(function () { assert_not_equals(performanceNamespace, undefined, msg); }, msg); + } + + if (child_name !== undefined) { + var msg2 = 'window.performance.' + child_name + ' is defined'; + wp_test(function() { assert_not_equals(performanceNamespace[child_name], undefined, msg2); }, msg2); + } +} + +function test_attribute_exists(parent_name, attribute_name, properties) +{ + var msg = 'window.performance.' + parent_name + '.' + attribute_name + ' is defined.'; + wp_test(function() { assert_not_equals(performanceNamespace[parent_name][attribute_name], undefined, msg); }, msg, properties); +} + +function test_enum(parent_name, enum_name, value, properties) +{ + var msg = 'window.performance.' + parent_name + '.' + enum_name + ' is defined.'; + wp_test(function() { assert_not_equals(performanceNamespace[parent_name][enum_name], undefined, msg); }, msg, properties); + + msg = 'window.performance.' + parent_name + '.' + enum_name + ' = ' + value; + wp_test(function() { assert_equals(performanceNamespace[parent_name][enum_name], value, msg); }, msg, properties); +} + +function test_timing_order(attribute_name, greater_than_attribute, properties) +{ + // ensure it's not 0 first + var msg = "window.performance.timing." + attribute_name + " > 0"; + wp_test(function() { assert_true(performanceNamespace.timing[attribute_name] > 0, msg); }, msg, properties); + + // ensure it's in the right order + msg = "window.performance.timing." + attribute_name + " >= window.performance.timing." + greater_than_attribute; + wp_test(function() { assert_true(performanceNamespace.timing[attribute_name] >= performanceNamespace.timing[greater_than_attribute], msg); }, msg, properties); +} + +function test_timing_greater_than(attribute_name, greater_than, properties) +{ + var msg = "window.performance.timing." + attribute_name + " > " + greater_than; + test_greater_than(performanceNamespace.timing[attribute_name], greater_than, msg, properties); +} + +function test_timing_equals(attribute_name, equals, msg, properties) +{ + var test_msg = msg || "window.performance.timing." + attribute_name + " == " + equals; + test_equals(performanceNamespace.timing[attribute_name], equals, test_msg, properties); +} + +// +// Non-test related helper functions +// + +function sleep_milliseconds(n) +{ + var start = new Date().getTime(); + while (true) { + if ((new Date().getTime() - start) >= n) break; + } +} + +// +// Common helper functions +// + +function test_greater_than(value, greater_than, msg, properties) +{ + wp_test(function () { assert_true(value > greater_than, msg); }, msg, properties); +} + +function test_greater_or_equals(value, greater_than, msg, properties) +{ + wp_test(function () { assert_true(value >= greater_than, msg); }, msg, properties); +} + +function test_not_equals(value, notequals, msg, properties) +{ + wp_test(function() { assert_not_equals(value, notequals, msg); }, msg, properties); +} diff --git a/test/fixtures/wpt/user-timing/resources/webperftestharnessextension.js b/test/fixtures/wpt/user-timing/resources/webperftestharnessextension.js new file mode 100644 index 00000000000000..8640918d4f255e --- /dev/null +++ b/test/fixtures/wpt/user-timing/resources/webperftestharnessextension.js @@ -0,0 +1,202 @@ +// +// Helper functions for User Timing tests +// + +var mark_names = [ + '', + '1', + 'abc', +]; + +var measures = [ + [''], + ['2', 1], + ['aaa', 'navigationStart', ''], +]; + +function test_method_exists(method, method_name, properties) +{ + var msg; + if (typeof method === 'function') + msg = 'performance.' + method.name + ' is supported!'; + else + msg = 'performance.' + method_name + ' is supported!'; + wp_test(function() { assert_equals(typeof method, 'function', msg); }, msg, properties); +} + +function test_method_throw_exception(func_str, exception, msg) +{ + let exception_name; + let test_func; + if (typeof exception == "function") { + exception_name = exception.name; + test_func = assert_throws_js; + } else { + exception_name = exception; + test_func = assert_throws_dom; + } + var msg = 'Invocation of ' + func_str + ' should throw ' + exception_name + ' Exception.'; + wp_test(function() { test_func(exception, function() {eval(func_str)}, msg); }, msg); +} + +function test_noless_than(value, greater_than, msg, properties) +{ + wp_test(function () { assert_true(value >= greater_than, msg); }, msg, properties); +} + +function test_fail(msg, properties) +{ + wp_test(function() { assert_unreached(); }, msg, properties); +} + +function test_resource_entries(entries, expected_entries) +{ + // This is slightly convoluted so that we can sort the output. + var actual_entries = {}; + var origin = window.location.protocol + "//" + window.location.host; + + for (var i = 0; i < entries.length; ++i) { + var entry = entries[i]; + var found = false; + for (var expected_entry in expected_entries) { + if (entry.name == origin + expected_entry) { + found = true; + if (expected_entry in actual_entries) { + test_fail(expected_entry + ' is not expected to have duplicate entries'); + } + actual_entries[expected_entry] = entry; + break; + } + } + if (!found) { + test_fail(entries[i].name + ' is not expected to be in the Resource Timing buffer'); + } + } + + sorted_urls = []; + for (var i in actual_entries) { + sorted_urls.push(i); + } + sorted_urls.sort(); + for (var i in sorted_urls) { + var url = sorted_urls[i]; + test_equals(actual_entries[url].initiatorType, + expected_entries[url], + origin + url + ' is expected to have initiatorType ' + expected_entries[url]); + } + for (var j in expected_entries) { + if (!(j in actual_entries)) { + test_fail(origin + j + ' is expected to be in the Resource Timing buffer'); + } + } +} + +function performance_entrylist_checker(type) +{ + const entryType = type; + + function entry_check(entry, expectedNames, testDescription = '') + { + const msg = testDescription + 'Entry \"' + entry.name + '\" should be one that we have set.'; + wp_test(function() { assert_in_array(entry.name, expectedNames, msg); }, msg); + test_equals(entry.entryType, entryType, testDescription + 'entryType should be \"' + entryType + '\".'); + if (type === "measure") { + test_true(isFinite(entry.startTime), testDescription + 'startTime should be a number.'); + test_true(isFinite(entry.duration), testDescription + 'duration should be a number.'); + } else if (type === "mark") { + test_greater_than(entry.startTime, 0, testDescription + 'startTime should greater than 0.'); + test_equals(entry.duration, 0, testDescription + 'duration of mark should be 0.'); + } + } + + function entrylist_order_check(entryList) + { + let inOrder = true; + for (let i = 0; i < entryList.length - 1; ++i) + { + if (entryList[i + 1].startTime < entryList[i].startTime) { + inOrder = false; + break; + } + } + return inOrder; + } + + function entrylist_check(entryList, expectedLength, expectedNames, testDescription = '') + { + test_equals(entryList.length, expectedLength, testDescription + 'There should be ' + expectedLength + ' entries.'); + test_true(entrylist_order_check(entryList), testDescription + 'Entries in entrylist should be in order.'); + for (let i = 0; i < entryList.length; ++i) + { + entry_check(entryList[i], expectedNames, testDescription + 'Entry_list ' + i + '. '); + } + } + + return{"entrylist_check":entrylist_check}; +} + +function PerformanceContext(context) +{ + this.performanceContext = context; +} + +PerformanceContext.prototype = +{ + + initialMeasures: function(item, index, array) + { + this.performanceContext.measure.apply(this.performanceContext, item); + }, + + mark: function() + { + this.performanceContext.mark.apply(this.performanceContext, arguments); + }, + + measure: function() + { + this.performanceContext.measure.apply(this.performanceContext, arguments); + }, + + clearMarks: function() + { + this.performanceContext.clearMarks.apply(this.performanceContext, arguments); + }, + + clearMeasures: function() + { + this.performanceContext.clearMeasures.apply(this.performanceContext, arguments); + + }, + + getEntries: function() + { + return this.performanceContext.getEntries.apply(this.performanceContext, arguments); + }, + + getEntriesByType: function() + { + return this.performanceContext.getEntriesByType.apply(this.performanceContext, arguments); + }, + + getEntriesByName: function() + { + return this.performanceContext.getEntriesByName.apply(this.performanceContext, arguments); + }, + + setResourceTimingBufferSize: function() + { + return this.performanceContext.setResourceTimingBufferSize.apply(this.performanceContext, arguments); + }, + + registerResourceTimingBufferFullCallback: function(func) + { + this.performanceContext.onresourcetimingbufferfull = func; + }, + + clearResourceTimings: function() + { + this.performanceContext.clearResourceTimings.apply(this.performanceContext, arguments); + } + +}; diff --git a/test/fixtures/wpt/user-timing/structured-serialize-detail.any.js b/test/fixtures/wpt/user-timing/structured-serialize-detail.any.js new file mode 100644 index 00000000000000..78771b2f7663d4 --- /dev/null +++ b/test/fixtures/wpt/user-timing/structured-serialize-detail.any.js @@ -0,0 +1,64 @@ +test(function() { + performance.clearMarks(); + const detail = { randomInfo: 123 } + const markEntry = new PerformanceMark("A", { detail }); + assert_equals(markEntry.detail.randomInfo, detail.randomInfo); + assert_not_equals(markEntry.detail, detail); +}, "The detail property in the mark constructor should be structured-clone."); + +test(function() { + performance.clearMarks(); + const detail = { randomInfo: 123 } + const markEntry = performance.mark("A", { detail }); + assert_not_equals(markEntry.detail, detail); +}, "The detail property in the mark method should be structured-clone."); + +test(function() { + performance.clearMarks(); + const markEntry = performance.mark("A"); + assert_equals(markEntry.detail, null); +}, "When accessing detail from a mark entry and the detail is not provided, just return a null value."); + +test(function() { + performance.clearMarks(); + const detail = { unserializable: Symbol() }; + assert_throws_dom("DataCloneError", ()=>{ + new PerformanceMark("A", { detail }); + }, "Trying to structured-serialize a Symbol."); +}, "Mark: Throw an exception when the detail property cannot be structured-serialized."); + +test(function() { + performance.clearMeasures(); + const detail = { randomInfo: 123 } + const measureEntry = performance.measure("A", { start: 0, detail }); + assert_not_equals(measureEntry.detail, detail); +}, "The detail property in the measure method should be structured-clone."); + +test(function() { + performance.clearMeasures(); + const detail = { randomInfo: 123 } + const measureEntry = performance.measure("A", { start: 0, detail }); + assert_equals(measureEntry.detail, measureEntry.detail); +}, "The detail property in the measure method should be the same reference."); + +test(function() { + performance.clearMeasures(); + const measureEntry = performance.measure("A"); + assert_equals(measureEntry.detail, null); +}, "When accessing detail from a measure entry and the detail is not provided, just return a null value."); + +test(function() { + performance.clearMeasures(); + const detail = { unserializable: Symbol() }; + assert_throws_dom("DataCloneError", ()=>{ + performance.measure("A", { start: 0, detail }); + }, "Trying to structured-serialize a Symbol."); +}, "Measure: Throw an exception when the detail property cannot be structured-serialized."); + +test(function() { + const bar = { 1: 2 }; + const detail = { foo: 1, bar }; + const mark = performance.mark("m", { detail }); + detail.foo = 2; + assert_equals(mark.detail.foo, 1); +}, "The detail object is cloned when passed to mark API."); diff --git a/test/fixtures/wpt/user-timing/supported-usertiming-types.any.js b/test/fixtures/wpt/user-timing/supported-usertiming-types.any.js new file mode 100644 index 00000000000000..ea3b2fe9dc90f7 --- /dev/null +++ b/test/fixtures/wpt/user-timing/supported-usertiming-types.any.js @@ -0,0 +1,37 @@ +test(() => { + if (typeof PerformanceObserver.supportedEntryTypes === "undefined") + assert_unreached("supportedEntryTypes is not supported."); + const types = PerformanceObserver.supportedEntryTypes; + assert_true(types.includes("mark"), + "There should be 'mark' in PerformanceObserver.supportedEntryTypes"); + assert_true(types.includes("measure"), + "There should be 'measure' in PerformanceObserver.supportedEntryTypes"); + assert_greater_than(types.indexOf("measure"), types.indexOf('mark'), + "The 'measure' entry should appear after the 'mark' entry"); +}, "supportedEntryTypes contains 'mark' and 'measure'."); + +if (typeof PerformanceObserver.supportedEntryTypes !== "undefined") { + const entryTypes = { + "mark": () => { + performance.mark('foo'); + }, + "measure": () => { + performance.measure('bar'); + } + } + for (let entryType in entryTypes) { + if (PerformanceObserver.supportedEntryTypes.includes(entryType)) { + promise_test(async() => { + await new Promise((resolve) => { + new PerformanceObserver(function (list, observer) { + observer.disconnect(); + resolve(); + }).observe({entryTypes: [entryType]}); + + // Force the PerformanceEntry. + entryTypes[entryType](); + }) + }, `'${entryType}' entries should be observable.`) + } + } +} diff --git a/test/fixtures/wpt/user-timing/user-timing-tojson.html b/test/fixtures/wpt/user-timing/user-timing-tojson.html new file mode 100644 index 00000000000000..6aef7fa904ab95 --- /dev/null +++ b/test/fixtures/wpt/user-timing/user-timing-tojson.html @@ -0,0 +1,44 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/user-timing/user_timing_exists.any.js b/test/fixtures/wpt/user-timing/user_timing_exists.any.js new file mode 100644 index 00000000000000..adf9052ebd58d8 --- /dev/null +++ b/test/fixtures/wpt/user-timing/user_timing_exists.any.js @@ -0,0 +1,12 @@ +test(function() { + assert_not_equals(self.performance.mark, undefined); +}, "self.performance.mark is defined."); +test(function() { + assert_not_equals(self.performance.clearMarks, undefined); +}, "self.performance.clearMarks is defined."); +test(function() { + assert_not_equals(self.performance.measure, undefined); +}, "self.performance.measure is defined."); +test(function() { + assert_not_equals(self.performance.clearMeasures, undefined); +}, "self.performance.clearMeasures is defined."); diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index fb10c7d403d730..2eda2919ea9908 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -1,6 +1,6 @@ { "common": { - "commit": "bb97a689743eb5e3bc0bc92ac41ab266c54c134e", + "commit": "03c5072affa496c5fd2a506e5c40d23e36b5e3aa", "path": "common" }, "console": { @@ -8,7 +8,7 @@ "path": "console" }, "dom/abort": { - "commit": "1728d198c92834d92f7f399ef35e7823d5bfa0e4", + "commit": "c49cafb491d99d6318f8f24a26936cc66501f412", "path": "dom/abort" }, "encoding": { @@ -36,11 +36,15 @@ "path": "html/webappapis/timers" }, "interfaces": { - "commit": "fcb671ed8b068b25cee87429d803833777f35c2c", + "commit": "fc086c82d5a7e9b01a684a23336d6d1f9e79e303", "path": "interfaces" }, + "performance-timeline": { + "commit": "17ebc3aea0d6321e69554067c39ab5855e6fb67e", + "path": "performance-timeline" + }, "resources": { - "commit": "972ca5b6693bffebebc5805e1b9da68a6876e1f6", + "commit": "fbee645164468c030072c46a934e2c876b143f8e", "path": "resources" }, "streams": { @@ -50,5 +54,13 @@ "url": { "commit": "77d54aa9e0405f737987b59331f3584e3e1c26f9", "path": "url" + }, + "user-timing": { + "commit": "df24fb604e2d40528ac1d1b5dd970e32fc5c2978", + "path": "user-timing" + }, + "WebCryptoAPI": { + "commit": "cdd0f03df41b222aed098fbbb11c6a3cc500a86b", + "path": "WebCryptoAPI" } } \ No newline at end of file diff --git a/test/js-native-api/test_function/test.js b/test/js-native-api/test_function/test.js index 988f128404e429..972adcd79f54b2 100644 --- a/test/js-native-api/test_function/test.js +++ b/test/js-native-api/test_function/test.js @@ -42,3 +42,11 @@ assert.deepStrictEqual(test_function.TestCreateFunctionParameters(), { cbIsNull: 'Invalid argument', resultIsNull: 'Invalid argument' }); + +assert.throws( + () => test_function.TestBadReturnExceptionPending(), + { + code: 'throwing exception', + name: 'Error' + } +); diff --git a/test/js-native-api/test_function/test_function.c b/test/js-native-api/test_function/test_function.c index 26445f4736dbdc..107727872a0655 100644 --- a/test/js-native-api/test_function/test_function.c +++ b/test/js-native-api/test_function/test_function.c @@ -138,6 +138,19 @@ static napi_value MakeTrackedFunction(napi_env env, napi_callback_info info) { return result; } +static napi_value TestBadReturnExceptionPending(napi_env env, napi_callback_info info) { + napi_throw_error(env, "throwing exception", "throwing exception"); + + // addons should only ever return a valid napi_value even if an + // exception occurs, but we have seen that the C++ wrapper + // with exceptions enabled sometimes returns an invalid value + // when an exception is thrown. Test that we ignore the return + // value then an exeption is pending. We use 0xFFFFFFFF as a value + // that should never be a valid napi_value and node seems to + // crash if it is not ignored indicating that it is indeed invalid. + return (napi_value)(0xFFFFFFFFF); +} + EXTERN_C_START napi_value Init(napi_env env, napi_value exports) { napi_value fn1; @@ -164,6 +177,12 @@ napi_value Init(napi_env env, napi_value exports) { env, "TestCreateFunctionParameters", NAPI_AUTO_LENGTH, TestCreateFunctionParameters, NULL, &fn5)); + napi_value fn6; + NODE_API_CALL(env, + napi_create_function( + env, "TestBadReturnExceptionPending", NAPI_AUTO_LENGTH, + TestBadReturnExceptionPending, NULL, &fn6)); + NODE_API_CALL(env, napi_set_named_property(env, exports, "TestCall", fn1)); NODE_API_CALL(env, napi_set_named_property(env, exports, "TestName", fn2)); NODE_API_CALL(env, @@ -175,6 +194,10 @@ napi_value Init(napi_env env, napi_value exports) { napi_set_named_property( env, exports, "TestCreateFunctionParameters", fn5)); + NODE_API_CALL(env, + napi_set_named_property( + env, exports, "TestBadReturnExceptionPending", fn6)); + return exports; } EXTERN_C_END diff --git a/test/parallel/test-abortcontroller.js b/test/parallel/test-abortcontroller.js index f7a70fbddbc89e..630a1c5708d765 100644 --- a/test/parallel/test-abortcontroller.js +++ b/test/parallel/test-abortcontroller.js @@ -56,10 +56,9 @@ const { ok, strictEqual, throws } = require('assert'); { // Tests that AbortSignal is impossible to construct manually const ac = new AbortController(); - throws( - () => new ac.signal.constructor(), - /^TypeError: Illegal constructor$/ - ); + throws(() => new ac.signal.constructor(), { + code: 'ERR_ILLEGAL_CONSTRUCTOR', + }); } { // Symbol.toStringTag diff --git a/test/parallel/test-blob-createobjecturl.js b/test/parallel/test-blob-createobjecturl.js new file mode 100644 index 00000000000000..a8fd377dd3ef70 --- /dev/null +++ b/test/parallel/test-blob-createobjecturl.js @@ -0,0 +1,48 @@ +// Flags: --no-warnings +'use strict'; + +const common = require('../common'); + +// Because registering a Blob URL requires generating a random +// UUID, it can only be done if crypto support is enabled. +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { + URL, +} = require('url'); + +const { + Blob, + resolveObjectURL, +} = require('buffer'); + +const assert = require('assert'); + +(async () => { + const blob = new Blob(['hello']); + const id = URL.createObjectURL(blob); + assert.strictEqual(typeof id, 'string'); + const otherBlob = resolveObjectURL(id); + assert.strictEqual(otherBlob.size, 5); + assert.strictEqual( + Buffer.from(await otherBlob.arrayBuffer()).toString(), + 'hello'); + URL.revokeObjectURL(id); + assert.strictEqual(resolveObjectURL(id), undefined); + + // Leaving a Blob registered should not cause an assert + // when Node.js exists + URL.createObjectURL(new Blob()); + +})().then(common.mustCall()); + +['not a url', undefined, 1, 'blob:nodedata:1:wrong', {}].forEach((i) => { + assert.strictEqual(resolveObjectURL(i), undefined); +}); + +[undefined, 1, '', false, {}].forEach((i) => { + assert.throws(() => URL.createObjectURL(i), { + code: 'ERR_INVALID_ARG_TYPE', + }); +}); diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js index 6c880e9dea1c84..2ac91ac99c9bcc 100644 --- a/test/parallel/test-blob.js +++ b/test/parallel/test-blob.js @@ -1,9 +1,11 @@ +// Flags: --no-warnings 'use strict'; const common = require('../common'); const assert = require('assert'); const { Blob } = require('buffer'); const { inspect } = require('util'); +const { EOL } = require('os'); { const b = new Blob(); @@ -45,15 +47,6 @@ assert.throws(() => new Blob({}), { assert.strictEqual(new Blob([], { type: {} }).type, '[object object]'); } -{ - const b = new Blob(['616263'], { encoding: 'hex', type: 'foo' }); - assert.strictEqual(b.size, 3); - assert.strictEqual(b.type, 'foo'); - b.text().then(common.mustCall((text) => { - assert.strictEqual(text, 'abc'); - })); -} - { const b = new Blob([Buffer.from('abc')]); assert.strictEqual(b.size, 3); @@ -198,3 +191,32 @@ assert.throws(() => new Blob({}), { 'Blob { size: 0, type: \'\' }'); assert.strictEqual(inspect(b, { depth: -1 }), '[Blob]'); } + +{ + // The Blob has to be over a specific size for the data to + // be copied asynchronously.. + const b = new Blob(['hello', 'there'.repeat(820)]); + assert.strictEqual(b.arrayBuffer(), b.arrayBuffer()); + b.arrayBuffer().then(common.mustCall()); +} + +(async () => { + const b = new Blob(['hello']); + const reader = b.stream().getReader(); + let res = await reader.read(); + assert.strictEqual(res.value.byteLength, 5); + assert(!res.done); + res = await reader.read(); + assert(res.done); +})().then(common.mustCall()); + +{ + const b = new Blob(['hello\n'], { endings: 'native' }); + assert.strictEqual(b.size, EOL.length + 5); + + [1, {}, 'foo'].forEach((endings) => { + assert.throws(() => new Blob([], { endings }), { + code: 'ERR_INVALID_ARG_VALUE', + }); + }); +} diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 0ca00f31adce8c..b88fc4c3a62a67 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -124,6 +124,7 @@ const expectedModules = new Set([ 'NativeModule internal/vm/module', 'NativeModule internal/worker/io', 'NativeModule internal/worker/js_transferable', + 'Internal Binding blob', 'NativeModule internal/blob', 'NativeModule async_hooks', 'NativeModule path', diff --git a/test/parallel/test-fs-cp.mjs b/test/parallel/test-fs-cp.mjs new file mode 100644 index 00000000000000..804b5a1f4c322c --- /dev/null +++ b/test/parallel/test-fs-cp.mjs @@ -0,0 +1,763 @@ +import { mustCall } from '../common/index.mjs'; + +import assert from 'assert'; +import fs from 'fs'; +const { + cp, + cpSync, + lstatSync, + mkdirSync, + readdirSync, + readFileSync, + readlinkSync, + symlinkSync, + statSync, + writeFileSync, +} = fs; +import net from 'net'; +import { join } from 'path'; +import { pathToFileURL } from 'url'; +import { setTimeout } from 'timers/promises'; + +const isWindows = process.platform === 'win32'; +import tmpdir from '../common/tmpdir.js'; +tmpdir.refresh(); + +let dirc = 0; +function nextdir() { + return join(tmpdir.path, `copy_${++dirc}`); +} + +// Synchronous implementation of copy. + +// It copies a nested folder structure with files and folders. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(src, dest, { recursive: true }); + assertDirEquivalent(src, dest); +} + +// It does not throw errors when directory is copied over and force is false. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + writeFileSync(join(src, 'README.md'), 'hello world', 'utf8'); + const dest = nextdir(); + cpSync(src, dest, { recursive: true }); + const initialStat = lstatSync(join(dest, 'README.md')); + cpSync(src, dest, { force: false, recursive: true }); + // File should not have been copied over, so access times will be identical: + assertDirEquivalent(src, dest); + const finalStat = lstatSync(join(dest, 'README.md')); + assert.strictEqual(finalStat.ctime.getTime(), initialStat.ctime.getTime()); +} + +// It overwrites existing files if force is true. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + writeFileSync(join(dest, 'README.md'), '# Goodbye', 'utf8'); + cpSync(src, dest, { recursive: true }); + assertDirEquivalent(src, dest); + const content = readFileSync(join(dest, 'README.md'), 'utf8'); + assert.strictEqual(content.trim(), '# Hello'); +} + +// It does not fail if the same directory is copied to dest twice, +// when dereference is true, and force is false (fails silently). +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + const destFile = join(dest, 'a/b/README2.md'); + cpSync(src, dest, { dereference: true, recursive: true }); + cpSync(src, dest, { dereference: true, recursive: true }); + const stat = lstatSync(destFile); + assert(stat.isFile()); +} + + +// It copies file itself, rather than symlink, when dereference is true. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + writeFileSync(join(src, 'foo.js'), 'foo', 'utf8'); + symlinkSync(join(src, 'foo.js'), join(src, 'bar.js')); + + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + const destFile = join(dest, 'foo.js'); + + cpSync(join(src, 'bar.js'), destFile, { dereference: true, recursive: true }); + const stat = lstatSync(destFile); + assert(stat.isFile()); +} + + +// It throws error when src and dest are identical. +{ + const src = './test/fixtures/copy/kitchen-sink'; + assert.throws( + () => cpSync(src, src), + { code: 'ERR_FS_CP_EINVAL' } + ); +} + +// It throws error if symlink in src points to location in dest. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = nextdir(); + mkdirSync(dest); + symlinkSync(dest, join(src, 'link')); + cpSync(src, dest, { recursive: true }); + assert.throws( + () => cpSync(src, dest, { recursive: true }), + { + code: 'ERR_FS_CP_EINVAL' + } + ); +} + +// It throws error if symlink in dest points to location in src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c')); + + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + symlinkSync(src, join(dest, 'a', 'c')); + assert.throws( + () => cpSync(src, dest, { recursive: true }), + { code: 'ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY' } + ); +} + +// It throws error if parent directory of symlink in dest points to src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a'), { recursive: true }); + const dest = nextdir(); + // Create symlink in dest pointing to src. + const destLink = join(dest, 'b'); + mkdirSync(dest, { recursive: true }); + symlinkSync(src, destLink); + assert.throws( + () => cpSync(src, join(dest, 'b', 'c')), + { code: 'ERR_FS_CP_EINVAL' } + ); +} + +// It throws error if attempt is made to copy directory to file. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = './test/fixtures/copy/kitchen-sink/README.md'; + assert.throws( + () => cpSync(src, dest), + { code: 'ERR_FS_CP_DIR_TO_NON_DIR' } + ); +} + +// It allows file to be copied to a file path. +{ + const srcFile = './test/fixtures/copy/kitchen-sink/index.js'; + const destFile = join(nextdir(), 'index.js'); + cpSync(srcFile, destFile, { dereference: true }); + const stat = lstatSync(destFile); + assert(stat.isFile()); +} + +// It throws error if directory copied without recursive flag. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + assert.throws( + () => cpSync(src, dest), + { code: 'ERR_FS_EISDIR' } + ); +} + + +// It throws error if attempt is made to copy file to directory. +{ + const src = './test/fixtures/copy/kitchen-sink/README.md'; + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + assert.throws( + () => cpSync(src, dest), + { code: 'ERR_FS_CP_NON_DIR_TO_DIR' } + ); +} + +// It throws error if attempt is made to copy to subdirectory of self. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = './test/fixtures/copy/kitchen-sink/a'; + assert.throws( + () => cpSync(src, dest), + { code: 'ERR_FS_CP_EINVAL' } + ); +} + +// It throws an error if attempt is made to copy socket. +if (!isWindows) { + const dest = nextdir(); + const sock = `${process.pid}.sock`; + const server = net.createServer(); + server.listen(sock); + assert.throws( + () => cpSync(sock, dest), + { code: 'ERR_FS_CP_SOCKET' } + ); + server.close(); +} + +// It copies timestamps from src to dest if preserveTimestamps is true. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(src, dest, { preserveTimestamps: true, recursive: true }); + assertDirEquivalent(src, dest); + const srcStat = lstatSync(join(src, 'index.js')); + const destStat = lstatSync(join(dest, 'index.js')); + assert.strictEqual(srcStat.mtime.getTime(), destStat.mtime.getTime()); +} + +// It applies filter function. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(src, dest, { + filter: (path) => { + const pathStat = statSync(path); + return pathStat.isDirectory() || path.endsWith('.js'); + }, + dereference: true, + recursive: true, + }); + const destEntries = []; + collectEntries(dest, destEntries); + for (const entry of destEntries) { + assert.strictEqual( + entry.isDirectory() || entry.name.endsWith('.js'), + true + ); + } +} + +// It throws error if filter function is asynchronous. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + assert.throws(() => { + cpSync(src, dest, { + filter: async (path) => { + await setTimeout(5, 'done'); + const pathStat = statSync(path); + return pathStat.isDirectory() || path.endsWith('.js'); + }, + dereference: true, + recursive: true, + }); + }, { code: 'ERR_INVALID_RETURN_VALUE' }); +} + +// It throws error if errorOnExist is true, force is false, and file or folder +// copied over. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(src, dest, { recursive: true }); + assert.throws( + () => cpSync(src, dest, { + dereference: true, + errorOnExist: true, + force: false, + recursive: true, + }), + { code: 'ERR_FS_CP_EEXIST' } + ); +} + +// It throws EEXIST error if attempt is made to copy symlink over file. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c')); + + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + writeFileSync(join(dest, 'a', 'c'), 'hello', 'utf8'); + assert.throws( + () => cpSync(src, dest, { recursive: true }), + { code: 'EEXIST' } + ); +} + +// It makes file writeable when updating timestamp, if not writeable. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + writeFileSync(join(src, 'foo.txt'), 'foo', { mode: 0o444 }); + cpSync(src, dest, { preserveTimestamps: true, recursive: true }); + assertDirEquivalent(src, dest); + const srcStat = lstatSync(join(src, 'foo.txt')); + const destStat = lstatSync(join(dest, 'foo.txt')); + assert.strictEqual(srcStat.mtime.getTime(), destStat.mtime.getTime()); +} + +// It copies link if it does not point to folder in src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(src, join(src, 'a', 'c')); + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + symlinkSync(dest, join(dest, 'a', 'c')); + cpSync(src, dest, { recursive: true }); + const link = readlinkSync(join(dest, 'a', 'c')); + assert.strictEqual(link, src); +} + +// It accepts file URL as src and dest. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(pathToFileURL(src), pathToFileURL(dest), { recursive: true }); + assertDirEquivalent(src, dest); +} + +// It throws if options is not object. +{ + assert.throws( + () => cpSync('a', 'b', () => {}), + { code: 'ERR_INVALID_ARG_TYPE' } + ); +} + +// Callback implementation of copy. + +// It copies a nested folder structure with files and folders. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + })); +} + +// It does not throw errors when directory is copied over and force is false. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + writeFileSync(join(src, 'README.md'), 'hello world', 'utf8'); + const dest = nextdir(); + cpSync(src, dest, { dereference: true, recursive: true }); + const initialStat = lstatSync(join(dest, 'README.md')); + cp(src, dest, { + dereference: true, + force: false, + recursive: true, + }, mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + // File should not have been copied over, so access times will be identical: + const finalStat = lstatSync(join(dest, 'README.md')); + assert.strictEqual(finalStat.ctime.getTime(), initialStat.ctime.getTime()); + })); +} + +// It overwrites existing files if force is true. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + writeFileSync(join(dest, 'README.md'), '# Goodbye', 'utf8'); + + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + const content = readFileSync(join(dest, 'README.md'), 'utf8'); + assert.strictEqual(content.trim(), '# Hello'); + })); +} + +// It does not fail if the same directory is copied to dest twice, +// when dereference is true, and force is false (fails silently). +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + const destFile = join(dest, 'a/b/README2.md'); + cpSync(src, dest, { dereference: true, recursive: true }); + cp(src, dest, { + dereference: true, + recursive: true + }, mustCall((err) => { + assert.strictEqual(err, null); + const stat = lstatSync(destFile); + assert(stat.isFile()); + })); +} + +// It copies file itself, rather than symlink, when dereference is true. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + writeFileSync(join(src, 'foo.js'), 'foo', 'utf8'); + symlinkSync(join(src, 'foo.js'), join(src, 'bar.js')); + + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + const destFile = join(dest, 'foo.js'); + + cp(join(src, 'bar.js'), destFile, { dereference: true }, + mustCall((err) => { + assert.strictEqual(err, null); + const stat = lstatSync(destFile); + assert(stat.isFile()); + }) + ); +} + +// It returns error when src and dest are identical. +{ + const src = './test/fixtures/copy/kitchen-sink'; + cp(src, src, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL'); + })); +} + +// It returns error if symlink in src points to location in dest. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = nextdir(); + mkdirSync(dest); + symlinkSync(dest, join(src, 'link')); + cpSync(src, dest, { recursive: true }); + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL'); + })); +} + +// It returns error if symlink in dest points to location in src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c')); + + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + symlinkSync(src, join(dest, 'a', 'c')); + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY'); + })); +} + +// It returns error if parent directory of symlink in dest points to src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a'), { recursive: true }); + const dest = nextdir(); + // Create symlink in dest pointing to src. + const destLink = join(dest, 'b'); + mkdirSync(dest, { recursive: true }); + symlinkSync(src, destLink); + cp(src, join(dest, 'b', 'c'), mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL'); + })); +} + +// It returns error if attempt is made to copy directory to file. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = './test/fixtures/copy/kitchen-sink/README.md'; + cp(src, dest, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_DIR_TO_NON_DIR'); + })); +} + +// It allows file to be copied to a file path. +{ + const srcFile = './test/fixtures/copy/kitchen-sink/README.md'; + const destFile = join(nextdir(), 'index.js'); + cp(srcFile, destFile, { dereference: true }, mustCall((err) => { + assert.strictEqual(err, null); + const stat = lstatSync(destFile); + assert(stat.isFile()); + })); +} + +// It returns error if directory copied without recursive flag. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(src, dest, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_EISDIR'); + })); +} + +// It returns error if attempt is made to copy file to directory. +{ + const src = './test/fixtures/copy/kitchen-sink/README.md'; + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + cp(src, dest, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_NON_DIR_TO_DIR'); + })); +} + +// It returns error if attempt is made to copy to subdirectory of self. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = './test/fixtures/copy/kitchen-sink/a'; + cp(src, dest, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL'); + })); +} + +// It returns an error if attempt is made to copy socket. +if (!isWindows) { + const dest = nextdir(); + const sock = `${process.pid}.sock`; + const server = net.createServer(); + server.listen(sock); + cp(sock, dest, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_SOCKET'); + server.close(); + })); +} + +// It copies timestamps from src to dest if preserveTimestamps is true. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(src, dest, { + preserveTimestamps: true, + recursive: true + }, mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + const srcStat = lstatSync(join(src, 'index.js')); + const destStat = lstatSync(join(dest, 'index.js')); + assert.strictEqual(srcStat.mtime.getTime(), destStat.mtime.getTime()); + })); +} + +// It applies filter function. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(src, dest, { + filter: (path) => { + const pathStat = statSync(path); + return pathStat.isDirectory() || path.endsWith('.js'); + }, + dereference: true, + recursive: true, + }, mustCall((err) => { + assert.strictEqual(err, null); + const destEntries = []; + collectEntries(dest, destEntries); + for (const entry of destEntries) { + assert.strictEqual( + entry.isDirectory() || entry.name.endsWith('.js'), + true + ); + } + })); +} + +// It supports async filter function. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(src, dest, { + filter: async (path) => { + await setTimeout(5, 'done'); + const pathStat = statSync(path); + return pathStat.isDirectory() || path.endsWith('.js'); + }, + dereference: true, + recursive: true, + }, mustCall((err) => { + assert.strictEqual(err, null); + const destEntries = []; + collectEntries(dest, destEntries); + for (const entry of destEntries) { + assert.strictEqual( + entry.isDirectory() || entry.name.endsWith('.js'), + true + ); + } + })); +} + +// It returns error if errorOnExist is true, force is false, and file or folder +// copied over. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cpSync(src, dest, { recursive: true }); + cp(src, dest, { + dereference: true, + errorOnExist: true, + force: false, + recursive: true, + }, mustCall((err) => { + assert.strictEqual(err.code, 'ERR_FS_CP_EEXIST'); + })); +} + +// It returns EEXIST error if attempt is made to copy symlink over file. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(join(src, 'a', 'b'), join(src, 'a', 'c')); + + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + writeFileSync(join(dest, 'a', 'c'), 'hello', 'utf8'); + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err.code, 'EEXIST'); + })); +} + +// It makes file writeable when updating timestamp, if not writeable. +{ + const src = nextdir(); + mkdirSync(src, { recursive: true }); + const dest = nextdir(); + mkdirSync(dest, { recursive: true }); + writeFileSync(join(src, 'foo.txt'), 'foo', { mode: 0o444 }); + cp(src, dest, { + preserveTimestamps: true, + recursive: true, + }, mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + const srcStat = lstatSync(join(src, 'foo.txt')); + const destStat = lstatSync(join(dest, 'foo.txt')); + assert.strictEqual(srcStat.mtime.getTime(), destStat.mtime.getTime()); + })); +} + +// It copies link if it does not point to folder in src. +{ + const src = nextdir(); + mkdirSync(join(src, 'a', 'b'), { recursive: true }); + symlinkSync(src, join(src, 'a', 'c')); + const dest = nextdir(); + mkdirSync(join(dest, 'a'), { recursive: true }); + symlinkSync(dest, join(dest, 'a', 'c')); + cp(src, dest, { recursive: true }, mustCall((err) => { + assert.strictEqual(err, null); + const link = readlinkSync(join(dest, 'a', 'c')); + assert.strictEqual(link, src); + })); +} + +// It accepts file URL as src and dest. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + cp(pathToFileURL(src), pathToFileURL(dest), { recursive: true }, + mustCall((err) => { + assert.strictEqual(err, null); + assertDirEquivalent(src, dest); + })); +} + +// It throws if options is not object. +{ + assert.throws( + () => cp('a', 'b', 'hello', () => {}), + { code: 'ERR_INVALID_ARG_TYPE' } + ); +} + +// Promises implementation of copy. + +// It copies a nested folder structure with files and folders. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + const p = await fs.promises.cp(src, dest, { recursive: true }); + assert.strictEqual(p, undefined); + assertDirEquivalent(src, dest); +} + +// It accepts file URL as src and dest. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + const p = await fs.promises.cp( + pathToFileURL(src), + pathToFileURL(dest), + { recursive: true } + ); + assert.strictEqual(p, undefined); + assertDirEquivalent(src, dest); +} + +// It allows async error to be caught. +{ + const src = './test/fixtures/copy/kitchen-sink'; + const dest = nextdir(); + await fs.promises.cp(src, dest, { recursive: true }); + await assert.rejects( + fs.promises.cp(src, dest, { + dereference: true, + errorOnExist: true, + force: false, + recursive: true, + }), + { code: 'ERR_FS_CP_EEXIST' } + ); +} + +// It rejects if options is not object. +{ + await assert.rejects( + fs.promises.cp('a', 'b', () => {}), + { code: 'ERR_INVALID_ARG_TYPE' } + ); +} + +function assertDirEquivalent(dir1, dir2) { + const dir1Entries = []; + collectEntries(dir1, dir1Entries); + const dir2Entries = []; + collectEntries(dir2, dir2Entries); + assert.strictEqual(dir1Entries.length, dir2Entries.length); + for (const entry1 of dir1Entries) { + const entry2 = dir2Entries.find((entry) => { + return entry.name === entry1.name; + }); + assert(entry2, `entry ${entry2.name} not copied`); + if (entry1.isFile()) { + assert(entry2.isFile(), `${entry2.name} was not file`); + } else if (entry1.isDirectory()) { + assert(entry2.isDirectory(), `${entry2.name} was not directory`); + } else if (entry1.isSymbolicLink()) { + assert(entry2.isSymbolicLink(), `${entry2.name} was not symlink`); + } + } +} + +function collectEntries(dir, dirEntries) { + const newEntries = readdirSync(dir, { withFileTypes: true }); + for (const entry of newEntries) { + if (entry.isDirectory()) { + collectEntries(join(dir, entry.name), dirEntries); + } + } + dirEntries.push(...newEntries); +} diff --git a/test/parallel/test-http-decoded-auth.js b/test/parallel/test-http-decoded-auth.js new file mode 100644 index 00000000000000..7b09f47cc7267c --- /dev/null +++ b/test/parallel/test-http-decoded-auth.js @@ -0,0 +1,48 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const testCases = [ + { + username: 'test@test"', + password: '123456^', + expected: 'dGVzdEB0ZXN0IjoxMjM0NTZe' + }, + { + username: 'test%40test', + password: '123456', + expected: 'dGVzdEB0ZXN0OjEyMzQ1Ng==' + }, + { + username: 'not%3Agood', + password: 'god', + expected: 'bm90Omdvb2Q6Z29k' + }, + { + username: 'not%22good', + password: 'g%5Eod', + expected: 'bm90Imdvb2Q6Z15vZA==' + }, + { + username: 'test1234::::', + password: 'mypass', + expected: 'dGVzdDEyMzQ6Ojo6Om15cGFzcw==' + }, +]; + +for (const testCase of testCases) { + const server = http.createServer(function(request, response) { + // The correct authorization header is be passed + assert.strictEqual(request.headers.authorization, `Basic ${testCase.expected}`); + response.writeHead(200, {}); + response.end('ok'); + server.close(); + }); + + server.listen(0, function() { + // make the request + const url = new URL(`http://${testCase.username}:${testCase.password}@localhost:${this.address().port}`); + http.request(url).end(); + }); +} diff --git a/test/parallel/test-http-write-head-2.js b/test/parallel/test-http-write-head-2.js index 248ac45ac49f8f..a47d0d72e3be56 100644 --- a/test/parallel/test-http-write-head-2.js +++ b/test/parallel/test-http-write-head-2.js @@ -29,7 +29,7 @@ const http = require('http'); res.end(); })); - server.listen(0, common.mustCall(function() { + server.listen(0, common.mustCall(() => { http.get({ port: server.address().port }, common.mustCall((res) => { assert.strictEqual(res.headers.test, '1'); assert.strictEqual(res.headers.test2, '2'); @@ -51,7 +51,7 @@ const http = require('http'); res.end(); })); - server.listen(0, common.mustCall(function() { + server.listen(0, common.mustCall(() => { http.get({ port: server.address().port }, common.mustCall((res) => { res.resume().on('end', common.mustCall(() => { server.close(); diff --git a/test/parallel/test-http2-buffersize.js b/test/parallel/test-http2-buffersize.js index 9d7355f1a0b750..68bb4315fd068b 100644 --- a/test/parallel/test-http2-buffersize.js +++ b/test/parallel/test-http2-buffersize.js @@ -5,7 +5,7 @@ if (!hasCrypto) skip('missing crypto'); const assert = require('assert'); const { createServer, connect } = require('http2'); -const { once } = require('events'); +const Countdown = require('../common/countdown'); // This test ensures that `bufferSize` of Http2Session and Http2Stream work // as expected. @@ -16,20 +16,18 @@ const { once } = require('events'); const server = createServer(); let client; + const countdown = new Countdown(kSockets, () => { + client.close(); + server.close(); + }); - const getStream = async () => { - const [ stream ] = await once(server, 'stream'); + server.on('stream', mustCall((stream) => { stream.on('data', mustCall()); stream.on('end', mustCall()); - stream.on('close', mustCall()); - return once(stream, 'close'); - }; - - const promises = [...new Array(kSockets)].map(getStream); - Promise.all(promises).then(mustCall(() => { - client.close(); - server.close(); - })); + stream.on('close', mustCall(() => { + countdown.dec(); + })); + }, kSockets)); server.listen(0, mustCall(() => { const authority = `http://localhost:${server.address().port}`; diff --git a/test/parallel/test-perf-gc-crash.js b/test/parallel/test-perf-gc-crash.js new file mode 100644 index 00000000000000..d980e91a2f2799 --- /dev/null +++ b/test/parallel/test-perf-gc-crash.js @@ -0,0 +1,25 @@ +'use strict'; + +require('../common'); + +// Refers to https://github.com/nodejs/node/issues/39548 + +// The test fails if this crashes. If it closes normally, +// then all is good. + +const { + PerformanceObserver, +} = require('perf_hooks'); + +// We don't actually care if the observer callback is called here. +const gcObserver = new PerformanceObserver(() => {}); + +gcObserver.observe({ entryTypes: ['gc'] }); + +gcObserver.disconnect(); + +const gcObserver2 = new PerformanceObserver(() => {}); + +gcObserver2.observe({ entryTypes: ['gc'] }); + +gcObserver2.disconnect(); diff --git a/test/parallel/test-perf-hooks-histogram.js b/test/parallel/test-perf-hooks-histogram.js index 323dbeb153633a..a60d3a94bbc136 100644 --- a/test/parallel/test-perf-hooks-histogram.js +++ b/test/parallel/test-perf-hooks-histogram.js @@ -78,8 +78,5 @@ const { inspect } = require('util'); { // Tests that RecordableHistogram is impossible to construct manually const h = createHistogram(); - assert.throws( - () => new h.constructor(), - /^TypeError: illegal constructor$/ - ); + assert.throws(() => new h.constructor(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); } diff --git a/test/parallel/test-perf-hooks-usertiming.js b/test/parallel/test-perf-hooks-usertiming.js index 401d0a6816481a..e7ef26889eae0f 100644 --- a/test/parallel/test-perf-hooks-usertiming.js +++ b/test/parallel/test-perf-hooks-usertiming.js @@ -29,7 +29,7 @@ assert(measure); assert.strictEqual(m.entryType, 'mark'); assert.strictEqual(typeof m.startTime, 'number'); assert.strictEqual(m.duration, 0); - assert.strictEqual(m.details, undefined); + assert.strictEqual(m.detail, null); }); clearMarks(); @@ -38,11 +38,18 @@ assert.throws(() => mark(Symbol('a')), { message: /Cannot convert a Symbol value to a string/ }); -[undefined, null, 1, 'any', {}, []].forEach((detail) => { +[undefined, null].forEach((detail) => { const m = mark('a', { detail }); assert.strictEqual(m.name, 'a'); assert.strictEqual(m.entryType, 'mark'); - assert.strictEqual(m.detail, detail); + assert.deepStrictEqual(m.detail, null); +}); +[1, 'any', {}, []].forEach((detail) => { + const m = mark('a', { detail }); + assert.strictEqual(m.name, 'a'); + assert.strictEqual(m.entryType, 'mark'); + // Value of detail is structured cloned. + assert.deepStrictEqual(m.detail, detail); }); clearMarks(); diff --git a/test/parallel/test-policy-crypto-default-encoding.js b/test/parallel/test-policy-crypto-default-encoding.js new file mode 100644 index 00000000000000..1f62b4d85a3c4f --- /dev/null +++ b/test/parallel/test-policy-crypto-default-encoding.js @@ -0,0 +1,34 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +common.requireNoPackageJSONAbove(); + +const fixtures = require('../common/fixtures'); + +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const encodings = ['buffer', 'utf8', 'utf16le', 'latin1', 'base64', 'hex']; + +for (const encoding of encodings) { + const dep = fixtures.path('policy', 'crypto-default-encoding', 'parent.js'); + const depPolicy = fixtures.path( + 'policy', + 'crypto-default-encoding', + 'policy.json'); + const { status } = spawnSync( + process.execPath, + [ + '--experimental-policy', depPolicy, dep, + ], + { + env: { + ...process.env, + DEFAULT_ENCODING: encoding + } + } + ); + assert.strictEqual(status, 0); +} diff --git a/test/parallel/test-stdio-undestroy.js b/test/parallel/test-stdio-undestroy.js new file mode 100644 index 00000000000000..b525672db27c5a --- /dev/null +++ b/test/parallel/test-stdio-undestroy.js @@ -0,0 +1,36 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + process.stdout.destroy(); + process.stderr.destroy(); + console.log('stdout'); + process.stdout.write('rocks\n'); + console.error('stderr'); + setTimeout(function() { + process.stderr.write('rocks too\n'); + }, 10); + return; +} + +const proc = spawn(process.execPath, [__filename, 'child'], { stdio: 'pipe' }); + +let stdout = ''; +proc.stdout.setEncoding('utf8'); +proc.stdout.on('data', common.mustCallAtLeast(function(chunk) { + stdout += chunk; +}, 1)); + +let stderr = ''; +proc.stderr.setEncoding('utf8'); +proc.stderr.on('data', common.mustCallAtLeast(function(chunk) { + stderr += chunk; +}, 1)); + +proc.on('exit', common.mustCall(function(exitCode) { + assert.strictEqual(exitCode, 0); + assert.strictEqual(stdout, 'stdout\nrocks\n'); + assert.strictEqual(stderr, 'stderr\nrocks too\n'); +})); diff --git a/test/parallel/test-stream-consumers.js b/test/parallel/test-stream-consumers.js new file mode 100644 index 00000000000000..1a3b6ce00200d4 --- /dev/null +++ b/test/parallel/test-stream-consumers.js @@ -0,0 +1,248 @@ +// Flags: --no-warnings +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const { + arrayBuffer, + blob, + buffer, + text, + json, +} = require('stream/consumers'); + +const { + PassThrough +} = require('stream'); + +const { + TransformStream, +} = require('stream/web'); + +const buf = Buffer.from('hellothere'); +const kArrayBuffer = + buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + +{ + const passthrough = new PassThrough(); + + blob(passthrough).then(common.mustCall(async (blob) => { + assert.strictEqual(blob.size, 10); + assert.deepStrictEqual(await blob.arrayBuffer(), kArrayBuffer); + })); + + passthrough.write('hello'); + setTimeout(() => passthrough.end('there'), 10); +} + +{ + const passthrough = new PassThrough(); + + arrayBuffer(passthrough).then(common.mustCall(async (ab) => { + assert.strictEqual(ab.byteLength, 10); + assert.deepStrictEqual(ab, kArrayBuffer); + })); + + passthrough.write('hello'); + setTimeout(() => passthrough.end('there'), 10); +} + +{ + const passthrough = new PassThrough(); + + buffer(passthrough).then(common.mustCall(async (buf) => { + assert.strictEqual(buf.byteLength, 10); + assert.deepStrictEqual(buf.buffer, kArrayBuffer); + })); + + passthrough.write('hello'); + setTimeout(() => passthrough.end('there'), 10); +} + + +{ + const passthrough = new PassThrough(); + + text(passthrough).then(common.mustCall(async (str) => { + assert.strictEqual(str.length, 10); + assert.deepStrictEqual(str, 'hellothere'); + })); + + passthrough.write('hello'); + setTimeout(() => passthrough.end('there'), 10); +} + +{ + const passthrough = new PassThrough(); + + json(passthrough).then(common.mustCall(async (str) => { + assert.strictEqual(str.length, 10); + assert.deepStrictEqual(str, 'hellothere'); + })); + + passthrough.write('"hello'); + setTimeout(() => passthrough.end('there"'), 10); +} + +{ + const { writable, readable } = new TransformStream(); + + blob(readable).then(common.mustCall(async (blob) => { + assert.strictEqual(blob.size, 10); + assert.deepStrictEqual(await blob.arrayBuffer(), kArrayBuffer); + })); + + const writer = writable.getWriter(); + writer.write('hello'); + setTimeout(() => { + writer.write('there'); + writer.close(); + }, 10); + + assert.rejects(blob(readable), { code: 'ERR_INVALID_STATE' }); +} + +{ + const { writable, readable } = new TransformStream(); + + arrayBuffer(readable).then(common.mustCall(async (ab) => { + assert.strictEqual(ab.byteLength, 10); + assert.deepStrictEqual(ab, kArrayBuffer); + })); + + const writer = writable.getWriter(); + writer.write('hello'); + setTimeout(() => { + writer.write('there'); + writer.close(); + }, 10); + + assert.rejects(arrayBuffer(readable), { code: 'ERR_INVALID_STATE' }); +} + +{ + const { writable, readable } = new TransformStream(); + + text(readable).then(common.mustCall(async (str) => { + assert.strictEqual(str.length, 10); + assert.deepStrictEqual(str, 'hellothere'); + })); + + const writer = writable.getWriter(); + writer.write('hello'); + setTimeout(() => { + writer.write('there'); + writer.close(); + }, 10); + + assert.rejects(text(readable), { code: 'ERR_INVALID_STATE' }); +} + +{ + const { writable, readable } = new TransformStream(); + + json(readable).then(common.mustCall(async (str) => { + assert.strictEqual(str.length, 10); + assert.deepStrictEqual(str, 'hellothere'); + })); + + const writer = writable.getWriter(); + writer.write('"hello'); + setTimeout(() => { + writer.write('there"'); + writer.close(); + }, 10); + + assert.rejects(json(readable), { code: 'ERR_INVALID_STATE' }); +} + +{ + const stream = new PassThrough({ + readableObjectMode: true, + writableObjectMode: true, + }); + + blob(stream).then(common.mustCall((blob) => { + assert.strictEqual(blob.size, 30); + })); + + stream.write({}); + stream.end({}); +} + +{ + const stream = new PassThrough({ + readableObjectMode: true, + writableObjectMode: true, + }); + + arrayBuffer(stream).then(common.mustCall((ab) => { + assert.strictEqual(ab.byteLength, 30); + assert.strictEqual( + Buffer.from(ab).toString(), + '[object Object][object Object]'); + })); + + stream.write({}); + stream.end({}); +} + +{ + const stream = new PassThrough({ + readableObjectMode: true, + writableObjectMode: true, + }); + + buffer(stream).then(common.mustCall((buf) => { + assert.strictEqual(buf.byteLength, 30); + assert.strictEqual( + buf.toString(), + '[object Object][object Object]'); + })); + + stream.write({}); + stream.end({}); +} + +{ + const stream = new PassThrough({ + readableObjectMode: true, + writableObjectMode: true, + }); + + assert.rejects(text(stream), { + code: 'ERR_INVALID_ARG_TYPE', + }); + + stream.write({}); + stream.end({}); +} + +{ + const stream = new PassThrough({ + readableObjectMode: true, + writableObjectMode: true, + }); + + assert.rejects(json(stream), { + code: 'ERR_INVALID_ARG_TYPE', + }); + + stream.write({}); + stream.end({}); +} + +{ + const stream = new TransformStream(); + text(stream.readable).then(common.mustCall((str) => { + // Incomplete utf8 character is flushed as a replacement char + assert.strictEqual(str.charCodeAt(0), 0xfffd); + })); + const writer = stream.writable.getWriter(); + Promise.all([ + writer.write(new Uint8Array([0xe2])), + writer.write(new Uint8Array([0x82])), + writer.close(), + ]).then(common.mustCall()); +} diff --git a/test/parallel/test-stream-readable-didRead.js b/test/parallel/test-stream-readable-didRead.js new file mode 100644 index 00000000000000..7508dd76899013 --- /dev/null +++ b/test/parallel/test-stream-readable-didRead.js @@ -0,0 +1,104 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Readable = require('stream').Readable; + +function noop() {} + +function check(readable, data, fn) { + assert.strictEqual(readable.readableDidRead, false); + if (data === -1) { + readable.on('error', common.mustCall()); + readable.on('data', common.mustNotCall()); + readable.on('end', common.mustNotCall()); + } else { + readable.on('error', common.mustNotCall()); + if (data === -2) { + readable.on('end', common.mustNotCall()); + } else { + readable.on('end', common.mustCall()); + } + if (data > 0) { + readable.on('data', common.mustCallAtLeast(data)); + } else { + readable.on('data', common.mustNotCall()); + } + } + readable.on('close', common.mustCall()); + fn(); + setImmediate(() => { + assert.strictEqual(readable.readableDidRead, true); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, 0, () => { + readable.read(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, 0, () => { + readable.resume(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, -2, () => { + readable.destroy(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + + check(readable, -1, () => { + readable.destroy(new Error()); + }); +} + +{ + const readable = new Readable({ + read() { + this.push('data'); + this.push(null); + } + }); + + check(readable, 1, () => { + readable.on('data', noop); + }); +} + +{ + const readable = new Readable({ + read() { + this.push('data'); + this.push(null); + } + }); + + check(readable, 1, () => { + readable.on('data', noop); + readable.off('data', noop); + }); +} diff --git a/test/parallel/test-trace-events-fs-sync.js b/test/parallel/test-trace-events-fs-sync.js index 69a0ae2778245a..78a5059bc91f5f 100644 --- a/test/parallel/test-trace-events-fs-sync.js +++ b/test/parallel/test-trace-events-fs-sync.js @@ -23,7 +23,7 @@ tests['fs.sync.chmod'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'fs.chmodSync("fs.txt",100);' + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.chown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.chownSync("fs.txt",' + uid + ',' + gid + ');' + + `fs.chownSync("fs.txt", ${uid}, ${gid});` + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.close'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'fs.unlinkSync("fs.txt")'; @@ -36,7 +36,7 @@ tests['fs.sync.fchmod'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.fchown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.fchownSync(fd,' + uid + ',' + gid + ');' + + `fs.fchownSync(fd, ${uid}, ${gid});` + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.fdatasync'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'const fd = fs.openSync("fs.txt", "r+");' + @@ -58,7 +58,7 @@ tests['fs.sync.futimes'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'fs.futimesSync(fd,1,1);' + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.lchown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.lchownSync("fs.txt",' + uid + ',' + gid + ');' + + `fs.lchownSync("fs.txt", ${uid}, ${gid});` + 'fs.unlinkSync("fs.txt")'; tests['fs.sync.link'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + 'fs.linkSync("fs.txt", "linkx");' + diff --git a/test/parallel/test-validators.js b/test/parallel/test-validators.js index 9dbf5f9c4599f2..6b0d49c6997a65 100644 --- a/test/parallel/test-validators.js +++ b/test/parallel/test-validators.js @@ -55,9 +55,9 @@ const invalidArgValueError = { }, invalidArgTypeError); }); - validateArray([1], 'foo', { minLength: 1 }); + validateArray([1], 'foo', 1); assert.throws(() => { - validateArray([], 'foo', { minLength: 1 }); + validateArray([], 'foo', 1); }, invalidArgValueError); } diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index e94a7b4488222a..502c86cf32abf3 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -657,9 +657,7 @@ const vectors = { })().then(common.mustCall()); // End user code cannot create CryptoKey directly -assert.throws(() => new CryptoKey(), { - code: 'ERR_OPERATION_FAILED' -}); +assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); { const buffer = Buffer.from('Hello World'); diff --git a/test/parallel/test-worker-broadcastchannel.js b/test/parallel/test-worker-broadcastchannel.js index 4212e5bf2f7afb..8e588994aab666 100644 --- a/test/parallel/test-worker-broadcastchannel.js +++ b/test/parallel/test-worker-broadcastchannel.js @@ -151,3 +151,20 @@ assert.throws(() => new BroadcastChannel(), { bc1.close(); bc2.close(); } + +{ + assert.throws(() => Reflect.get(BroadcastChannel.prototype, 'name', {}), { + code: 'ERR_INVALID_THIS', + }); + + [ + 'close', + 'postMessage', + 'ref', + 'unref', + ].forEach((i) => { + assert.throws(() => Reflect.apply(BroadcastChannel.prototype[i], [], {}), { + code: 'ERR_INVALID_THIS', + }); + }); +} diff --git a/test/sequential/test-debugger-breakpoint-exists.js b/test/sequential/test-debugger-breakpoint-exists.js new file mode 100644 index 00000000000000..7be0ba657fa981 --- /dev/null +++ b/test/sequential/test-debugger-breakpoint-exists.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const fixtures = require('../common/fixtures'); +const startCLI = require('../common/debugger'); + +// Test for "Breakpoint at specified location already exists" error. +{ + const script = fixtures.path('debugger', 'three-lines.js'); + const cli = startCLI([script]); + + function onFatal(error) { + cli.quit(); + throw error; + } + + cli.waitForInitialBreak() + .then(() => cli.waitForPrompt()) + .then(() => cli.command('setBreakpoint(1)')) + .then(() => cli.command('setBreakpoint(1)')) + .then(() => cli.waitFor(/Breakpoint at specified location already exists/)) + .then(() => cli.quit()) + .then(null, onFatal); +} diff --git a/test/sequential/test-debugger-heap-profiler.js b/test/sequential/test-debugger-heap-profiler.js index 0f0fdc22fbb3b4..86eb9d9d0d232f 100644 --- a/test/sequential/test-debugger-heap-profiler.js +++ b/test/sequential/test-debugger-heap-profiler.js @@ -3,24 +3,21 @@ const common = require('../common'); common.skipIfInspectorDisabled(); -if (!common.isMainThread) { - common.skip('process.chdir() is not available in workers'); -} - const fixtures = require('../common/fixtures'); const startCLI = require('../common/debugger'); const tmpdir = require('../common/tmpdir'); +const path = require('path'); tmpdir.refresh(); -process.chdir(tmpdir.path); const { readFileSync } = require('fs'); -const filename = 'node.heapsnapshot'; +const filename = path.join(tmpdir.path, 'node.heapsnapshot'); // Heap profiler take snapshot. { - const cli = startCLI([fixtures.path('debugger/empty.js')]); + const opts = { cwd: tmpdir.path }; + const cli = startCLI([fixtures.path('debugger/empty.js')], [], opts); function onFatal(error) { cli.quit(); @@ -32,6 +29,10 @@ const filename = 'node.heapsnapshot'; .then(() => cli.waitForPrompt()) .then(() => cli.command('takeHeapSnapshot()')) .then(() => JSON.parse(readFileSync(filename, 'utf8'))) + // Check that two simultaneous snapshots don't step all over each other. + // Refs: https://github.com/nodejs/node/issues/39555 + .then(() => cli.command('takeHeapSnapshot(); takeHeapSnapshot()')) + .then(() => JSON.parse(readFileSync(filename, 'utf8'))) .then(() => cli.quit()) .then(null, onFatal); } diff --git a/test/wpt/status/FileAPI/blob.json b/test/wpt/status/FileAPI/blob.json index c4b809b3b4036d..64163961e04b21 100644 --- a/test/wpt/status/FileAPI/blob.json +++ b/test/wpt/status/FileAPI/blob.json @@ -8,9 +8,6 @@ "Blob-slice.any.js": { "skip": "Depends on File API" }, - "Blob-stream.any.js": { - "skip": "Depends on Web Streams API" - }, "Blob-in-worker.worker.js": { "skip": "Depends on Web Workers API" } diff --git a/test/wpt/status/WebCryptoAPI.json b/test/wpt/status/WebCryptoAPI.json new file mode 100644 index 00000000000000..0f8489c871f037 --- /dev/null +++ b/test/wpt/status/WebCryptoAPI.json @@ -0,0 +1,90 @@ +{ + "derive_bits_keys/ecdh_bits.https.any.js": { + "fail": "Derived correct bits expected true got false" + }, + "derive_bits_keys/hkdf.https.any.js": { + "fail": "location is not defined" + }, + "derive_bits_keys/pbkdf2.https.any.js": { + "fail": "location is not defined" + }, + "digest/digest.https.any.js": { + "fail": "Expected NotSupportedError but got TypeError" + }, + "encrypt_decrypt/aes_cbc.https.any.js": { + "fail": "Expected OperationError but got Error" + }, + "encrypt_decrypt/rsa_oaep.https.any.js": { + "fail": "Expected OperationError but got Error" + }, + "generateKey/failures_AES-CBC.https.any.js": { + "fail": "Expected OperationError but got TypeError" + }, + "generateKey/failures_AES-CTR.https.any.js": { + "fail": "Expected OperationError but got TypeError" + }, + "generateKey/failures_AES-GCM.https.any.js": { + "fail": "Expected OperationError but got TypeError" + }, + "generateKey/failures_AES-KW.https.any.js": { + "fail": "Expected OperationError but got TypeError" + }, + "generateKey/failures_ECDH.https.any.js": { + "fail": "Expected NotSupportedError but got TypeError" + }, + "generateKey/failures_ECDSA.https.any.js": { + "fail": "Expected NotSupportedError but got TypeError" + }, + "generateKey/failures_HMAC.https.any.js": { + "fail": "Operation succeeded, but should not have Reached unreachable code" + }, + "generateKey/failures_RSA-OAEP.https.any.js": { + "fail": "Operation succeeded, but should not have Reached unreachable code" + }, + "generateKey/failures_RSA-PSS.https.any.js": { + "fail": "Operation succeeded, but should not have Reached unreachable code" + }, + "generateKey/failures_RSASSA-PKCS1-v1_5.https.any.js": { + "fail": "Operation succeeded, but should not have Reached unreachable code" + }, + "generateKey/successes_AES-CBC.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_AES-CTR.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_AES-GCM.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_AES-KW.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_ECDH.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_ECDSA.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_HMAC.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_RSA-OAEP.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_RSA-PSS.https.any.js": { + "fail": "location is not defined" + }, + "generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js": { + "fail": "location is not defined" + }, + "getRandomValues.any.js": { + "fail": "The data argument must be an integer-type TypedArray" + }, + "historical.any.js": { + "fail": "expected (undefined) undefined but got..." + }, + "idlharness.https.any.js": { + "fail": "Various non-IDL-compliant things" + } +} + diff --git a/test/wpt/status/performance-timeline.json b/test/wpt/status/performance-timeline.json new file mode 100644 index 00000000000000..6c845c681ae44d --- /dev/null +++ b/test/wpt/status/performance-timeline.json @@ -0,0 +1,11 @@ +{ + "case-sensitivity.any.js": { + "fail": "resource entry type not supported" + }, + "idlharness.any.js": { + "skip": "idlharness cannot recognize Node.js environment" + }, + "webtiming-resolution.any.js": { + "skip": "flaky" + } +} diff --git a/test/wpt/status/user-timing.json b/test/wpt/status/user-timing.json new file mode 100644 index 00000000000000..b1110e6a5e798d --- /dev/null +++ b/test/wpt/status/user-timing.json @@ -0,0 +1,11 @@ +{ + "invoke_with_timing_attributes.worker.js": { + "skip": "importScripts not supported" + }, + "performance-measure-invalid.worker.js": { + "skip": "importScripts not supported" + }, + "idlharness.any.js": { + "skip": "idlharness cannot recognize Node.js environment" + } +} diff --git a/test/wpt/test-blob.js b/test/wpt/test-blob.js index 92e18bc0ef2f22..0614c2d3fe36f1 100644 --- a/test/wpt/test-blob.js +++ b/test/wpt/test-blob.js @@ -7,7 +7,9 @@ const runner = new WPTRunner('FileAPI/blob'); runner.setInitScript(` const { Blob } = require('buffer'); + const { ReadableStream } = require('stream/web'); global.Blob = Blob; + global.ReadableStream = ReadableStream; `); runner.runJsTests(); diff --git a/test/wpt/test-performance-timeline.js b/test/wpt/test-performance-timeline.js new file mode 100644 index 00000000000000..12f1abd3a52a32 --- /dev/null +++ b/test/wpt/test-performance-timeline.js @@ -0,0 +1,29 @@ +'use strict'; +require('../common'); +const { WPTRunner } = require('../common/wpt'); + +const runner = new WPTRunner('performance-timeline'); + +// Needed to access to DOMException. +runner.setFlags(['--expose-internals']); + +runner.setInitScript(` + const { + PerformanceMark, + PerformanceMeasure, + PerformanceObserver, + PerformanceObserverEntryList, + performance, + } = require('perf_hooks'); + global.PerformanceMark = performance; + global.PerformanceMeasure = performance; + global.PerformanceObserver = PerformanceObserver; + global.PerformanceObserverEntryList = PerformanceObserverEntryList; + global.performance = performance; + + const { internalBinding } = require('internal/test/binding'); + const { DOMException } = internalBinding('messaging'); + global.DOMException = DOMException; +`); + +runner.runJsTests(); diff --git a/test/wpt/test-user-timing.js b/test/wpt/test-user-timing.js new file mode 100644 index 00000000000000..36d13297ba57cc --- /dev/null +++ b/test/wpt/test-user-timing.js @@ -0,0 +1,27 @@ +'use strict'; +require('../common'); +const { WPTRunner } = require('../common/wpt'); + +const runner = new WPTRunner('user-timing'); + +// Needed to access to DOMException. +runner.setFlags(['--expose-internals']); + +runner.setInitScript(` + const { + PerformanceMark, + PerformanceMeasure, + PerformanceObserver, + performance, + } = require('perf_hooks'); + global.PerformanceMark = performance; + global.PerformanceMeasure = performance; + global.PerformanceObserver = PerformanceObserver; + global.performance = performance; + + const { internalBinding } = require('internal/test/binding'); + const { DOMException } = internalBinding('messaging'); + global.DOMException = DOMException; +`); + +runner.runJsTests(); diff --git a/test/wpt/test-webcrypto.js b/test/wpt/test-webcrypto.js new file mode 100644 index 00000000000000..e8707a464f434c --- /dev/null +++ b/test/wpt/test-webcrypto.js @@ -0,0 +1,53 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { WPTRunner } = require('../common/wpt'); + +const runner = new WPTRunner('WebCryptoAPI'); + +// Set Node.js flags required for the tests. +runner.setFlags(['--expose-internals']); + +// Set a script that will be executed in the worker before running the tests. +runner.setInitScript(` + const { + Crypto, + SubtleCrypto, + crypto, + } = require('internal/crypto/webcrypto'); + const { internalBinding } = require('internal/test/binding'); + const { DOMException } = internalBinding('messaging'); + global.DOMException = DOMException; + + Object.defineProperties(global, { + Crypto: { + value: Crypto, + configurable: true, + writable: true, + enumerable: false, + }, + SubtleCrypto: { + value: SubtleCrypto, + configurable: true, + writable: true, + enumerable: false, + }, + CryptoKey: { + value: crypto.CryptoKey, + configurable: true, + writable: true, + enumerable: false, + }, + crypto: { + value: crypto, + configurable: true, + writable: true, + enumerable: false, + }, + }); +`); + +runner.runJsTests(); diff --git a/tools/find-inactive-collaborators.mjs b/tools/find-inactive-collaborators.mjs index 282a49dc965308..0d89d2869cf4f7 100755 --- a/tools/find-inactive-collaborators.mjs +++ b/tools/find-inactive-collaborators.mjs @@ -64,16 +64,19 @@ async function getCollaboratorsFromReadme() { crlfDelay: Infinity, }); const returnedArray = []; - let processingCollaborators = false; + let foundCollaboratorHeading = false; for await (const line of readmeText) { - const isCollaborator = processingCollaborators && line.length; - if (line === '### Collaborators') { - processingCollaborators = true; - } - if (line === '### Collaborator emeriti') { - processingCollaborators = false; + // If we've found the collaborator heading already, stop processing at the + // next heading. + if (foundCollaboratorHeading && line.startsWith('#')) { break; } + + const isCollaborator = foundCollaboratorHeading && line.length; + + if (line === '### Collaborators') { + foundCollaboratorHeading = true; + } if (line.startsWith('**') && isCollaborator) { const [, name, email] = /^\*\*([^*]+)\*\* <(.+)>/.exec(line); const mailmap = await runGitCommand( @@ -89,6 +92,11 @@ async function getCollaboratorsFromReadme() { }); } } + + if (!foundCollaboratorHeading) { + throw new Error('Could not find Collaborator section of README'); + } + return returnedArray; } diff --git a/tools/inspector_protocol/code_generator.py b/tools/inspector_protocol/code_generator.py index c1f78dc7492d78..0b8baea0ae710e 100755 --- a/tools/inspector_protocol/code_generator.py +++ b/tools/inspector_protocol/code_generator.py @@ -103,6 +103,17 @@ def init_defaults(config_tuple, path, defaults): ".lib": False, ".lib.export_macro": "", ".lib.export_header": False, + # The encoding lib consists of encoding/encoding.h and + # encoding/encoding.cc in its subdirectory, which binaries + # may link / depend on, instead of relying on the + # JINJA2 templates lib/encoding_{h,cc}.template. + # In that case, |header| identifies the include file + # and |namespace| is the namespace it's using. Usually + # inspector_protocol_encoding but for v8's copy it's + # v8_inspector_protocol_encoding. + # TODO(johannes): Migrate away from lib/encoding_{h,cc}.template + # in favor of this. + ".encoding_lib": { "header": "", "namespace": []}, } for key_value in config_values: parts = key_value.split("=") diff --git a/tools/inspector_protocol/encoding/encoding.cc b/tools/inspector_protocol/encoding/encoding.cc index c1078769c7feaf..636281dd8ad894 100644 --- a/tools/inspector_protocol/encoding/encoding.cc +++ b/tools/inspector_protocol/encoding/encoding.cc @@ -185,11 +185,10 @@ namespace internals { // |type| is the major type as specified in RFC 7049 Section 2.1. // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size // (e.g. for BYTE_STRING). -// If successful, returns the number of bytes read. Otherwise returns -1. -// TODO(johannes): change return type to size_t and use 0 for error. -int8_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { +// If successful, returns the number of bytes read. Otherwise returns 0. +size_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { if (bytes.empty()) - return -1; + return 0; uint8_t initial_byte = bytes[0]; *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); @@ -203,32 +202,32 @@ int8_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { if (additional_information == kAdditionalInformation1Byte) { // Values 24-255 are encoded with one initial byte, followed by the value. if (bytes.size() < 2) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 2; } if (additional_information == kAdditionalInformation2Bytes) { // Values 256-65535: 1 initial byte + 2 bytes payload. if (bytes.size() < 1 + sizeof(uint16_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 3; } if (additional_information == kAdditionalInformation4Bytes) { // 32 bit uint: 1 initial byte + 4 bytes payload. if (bytes.size() < 1 + sizeof(uint32_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 5; } if (additional_information == kAdditionalInformation8Bytes) { // 64 bit uint: 1 initial byte + 8 bytes payload. if (bytes.size() < 1 + sizeof(uint64_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 9; } - return -1; + return 0; } // Writes the start of a token with |type|. The |value| may indicate the size, @@ -770,10 +769,10 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { SetToken(CBORTokenTag::NULL_VALUE, 1); return; case kExpectedConversionToBase64Tag: { // BINARY - const int8_t bytes_read = internals::ReadTokenStart( + const size_t bytes_read = internals::ReadTokenStart( bytes_.subspan(status_.pos + 1), &token_start_type_, &token_start_internal_value_); - if (bytes_read < 0 || token_start_type_ != MajorType::BYTE_STRING || + if (!bytes_read || token_start_type_ != MajorType::BYTE_STRING || token_start_internal_value_ > kMaxValidLength) { SetError(Error::CBOR_INVALID_BINARY); return; @@ -823,47 +822,49 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { return; } default: { - const int8_t token_start_length = internals::ReadTokenStart( + const size_t bytes_read = internals::ReadTokenStart( bytes_.subspan(status_.pos), &token_start_type_, &token_start_internal_value_); - const bool success = token_start_length >= 0; switch (token_start_type_) { case MajorType::UNSIGNED: // INT32. // INT32 is a signed int32 (int32 makes sense for the // inspector_protocol, it's not a CBOR limitation), so we check // against the signed max, so that the allowable values are // 0, 1, 2, ... 2^31 - 1. - if (!success || + if (!bytes_read || static_cast(std::numeric_limits::max()) < static_cast(token_start_internal_value_)) { SetError(Error::CBOR_INVALID_INT32); return; } - SetToken(CBORTokenTag::INT32, token_start_length); + SetToken(CBORTokenTag::INT32, bytes_read); return; case MajorType::NEGATIVE: { // INT32. // INT32 is a signed int32 (int32 makes sense for the - // inspector_protocol, it's not a CBOR limitation); in CBOR, - // the negative values for INT32 are represented as NEGATIVE, - // that is, -1 INT32 is represented as 1 << 5 | 0 (major type 1, - // additional info value 0). So here, we compute the INT32 value - // and then check it against the INT32 min. - int64_t actual_value = - -static_cast(token_start_internal_value_) - 1; - if (!success || actual_value < std::numeric_limits::min()) { + // inspector_protocol, it's not a CBOR limitation); in CBOR, the + // negative values for INT32 are represented as NEGATIVE, that is, -1 + // INT32 is represented as 1 << 5 | 0 (major type 1, additional info + // value 0). + // The represented allowed values range is -1 to -2^31. + // They are mapped into the encoded range of 0 to 2^31-1. + // We check the the payload in token_start_internal_value_ against + // that range (2^31-1 is also known as + // std::numeric_limits::max()). + if (!bytes_read || + static_cast(token_start_internal_value_) > + static_cast(std::numeric_limits::max())) { SetError(Error::CBOR_INVALID_INT32); return; } - SetToken(CBORTokenTag::INT32, token_start_length); + SetToken(CBORTokenTag::INT32, bytes_read); return; } case MajorType::STRING: { // STRING8. - if (!success || token_start_internal_value_ > kMaxValidLength) { + if (!bytes_read || token_start_internal_value_ > kMaxValidLength) { SetError(Error::CBOR_INVALID_STRING8); return; } - uint64_t token_byte_length = - token_start_internal_value_ + token_start_length; + uint64_t token_byte_length = token_start_internal_value_ + bytes_read; if (token_byte_length > remaining_bytes) { SetError(Error::CBOR_INVALID_STRING8); return; @@ -875,13 +876,12 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { case MajorType::BYTE_STRING: { // STRING16. // Length must be divisible by 2 since UTF16 is 2 bytes per // character, hence the &1 check. - if (!success || token_start_internal_value_ > kMaxValidLength || + if (!bytes_read || token_start_internal_value_ > kMaxValidLength || token_start_internal_value_ & 1) { SetError(Error::CBOR_INVALID_STRING16); return; } - uint64_t token_byte_length = - token_start_internal_value_ + token_start_length; + uint64_t token_byte_length = token_start_internal_value_ + bytes_read; if (token_byte_length > remaining_bytes) { SetError(Error::CBOR_INVALID_STRING16); return; @@ -1857,7 +1857,7 @@ class JsonParser { // If the |Char| we're dealing with is really a byte, then // we have utf8 here, and we need to check for multibyte characters // and transcode them to utf16 (either one or two utf16 chars). - if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) { + if (sizeof(Char) == sizeof(uint8_t) && c > 0x7f) { // Inspect the leading byte to figure out how long the utf8 // byte sequence is; while doing this initialize |codepoint| // with the first few bits. @@ -1896,7 +1896,7 @@ class JsonParser { // Disallow overlong encodings for ascii characters, as these // would include " and other characters significant to JSON // string termination / control. - if (codepoint < 0x7f) + if (codepoint <= 0x7f) return false; // Invalid in UTF8, and can't be represented in UTF16 anyway. if (codepoint > 0x10ffff) diff --git a/tools/inspector_protocol/encoding/encoding.h b/tools/inspector_protocol/encoding/encoding.h index 90916d42b36dae..08596e9e1e43f0 100644 --- a/tools/inspector_protocol/encoding/encoding.h +++ b/tools/inspector_protocol/encoding/encoding.h @@ -427,7 +427,7 @@ Status AppendString8EntryToCBORMap(span string8_key, std::string* cbor); namespace internals { // Exposed only for writing tests. -int8_t ReadTokenStart(span bytes, +size_t ReadTokenStart(span bytes, cbor::MajorType* type, uint64_t* value); diff --git a/tools/inspector_protocol/encoding/encoding_test.cc b/tools/inspector_protocol/encoding/encoding_test.cc index b8d75e09baaf31..6893fe2581683c 100644 --- a/tools/inspector_protocol/encoding/encoding_test.cc +++ b/tools/inspector_protocol/encoding/encoding_test.cc @@ -234,6 +234,30 @@ TEST(EncodeDecodeInt32Test, RoundtripsInt32Max) { EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); } +TEST(EncodeDecodeInt32Test, RoundtripsInt32Min) { + // std::numeric_limits is encoded as a uint32 (4 unsigned bytes) + // after the initial byte, which effectively carries the sign by + // designating the token as NEGATIVE. + std::vector encoded; + EncodeInt32(std::numeric_limits::min(), &encoded); + // 1 for initial byte, 4 for the uint32. + // first three bits: major type = 1; + // remaining five bits: additional info = 26, indicating payload is uint32. + EXPECT_THAT(encoded, ElementsAreArray(std::array{ + {1 << 5 | 26, 0x7f, 0xff, 0xff, 0xff}})); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFrom(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(std::numeric_limits::min(), tokenizer.GetInt32()); + // It's nice to see how the min int32 value reads in hex: + // That is, -1 minus the unsigned payload (0x7fffffff, see above). + int32_t expected = -1 - 0x7fffffff; + EXPECT_EQ(expected, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + TEST(EncodeDecodeInt32Test, CantRoundtripUint32) { // 0xdeadbeef is a value which does not fit below // std::numerical_limits::max(), so we can't encode @@ -261,15 +285,21 @@ TEST(EncodeDecodeInt32Test, DecodeErrorCases) { std::vector data; std::string msg; }; - std::vector tests{ - {TestCase{ - {24}, - "additional info = 24 would require 1 byte of payload (but it's 0)"}, - TestCase{{27, 0xaa, 0xbb, 0xcc}, - "additional info = 27 would require 8 bytes of payload (but " - "it's 3)"}, - TestCase{{29}, "additional info = 29 isn't recognized"}}}; - + std::vector tests{{ + TestCase{ + {24}, + "additional info = 24 would require 1 byte of payload (but it's 0)"}, + TestCase{{27, 0xaa, 0xbb, 0xcc}, + "additional info = 27 would require 8 bytes of payload (but " + "it's 3)"}, + TestCase{{29}, "additional info = 29 isn't recognized"}, + TestCase{{1 << 5 | 27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "Max UINT64 payload is outside the allowed range"}, + TestCase{{1 << 5 | 26, 0xff, 0xff, 0xff, 0xff}, + "Max UINT32 payload is outside the allowed range"}, + TestCase{{1 << 5 | 26, 0x80, 0x00, 0x00, 0x00}, + "UINT32 payload w/ high bit set is outside the allowed range"}, + }}; for (const TestCase& test : tests) { SCOPED_TRACE(test.msg); CBORTokenizer tokenizer(SpanFrom(test.data)); @@ -1517,6 +1547,22 @@ TEST_F(JsonParserTest, SimpleDictionary) { log_.str()); } +TEST_F(JsonParserTest, UsAsciiDelCornerCase) { + // DEL (0x7f) is a 7 bit US-ASCII character, and while it is a control + // character according to Unicode, it's not considered a control + // character in https://tools.ietf.org/html/rfc7159#section-7, so + // it can be placed directly into the JSON string, without JSON escaping. + std::string json = "{\"foo\": \"a\x7f\"}"; + ParseJSON(GetTestPlatform(), SpanFrom(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: foo\n" + "string16: a\x7f\n" + "map end\n", + log_.str()); +} + TEST_F(JsonParserTest, Whitespace) { std::string json = "\n {\n\"msg\"\n: \v\"Hello, world.\"\t\r}\t"; ParseJSON(GetTestPlatform(), SpanFrom(json), &log_); diff --git a/tools/inspector_protocol/lib/Values_cpp.template b/tools/inspector_protocol/lib/Values_cpp.template index be3149d50356f2..8b4dfc91e3b9c9 100644 --- a/tools/inspector_protocol/lib/Values_cpp.template +++ b/tools/inspector_protocol/lib/Values_cpp.template @@ -6,6 +6,10 @@ //#include "Values.h" +{% if config.encoding_lib.header %} +#include "{{config.encoding_lib.header}}" +{% endif %} + {% for namespace in config.protocol.namespace %} namespace {{namespace}} { {% endfor %} @@ -64,6 +68,30 @@ void escapeStringForJSONInternal(const Char* str, unsigned len, // to this constant. static constexpr int kStackLimitValues = 1000; +{% if config.encoding_lib.namespace %} +using {{"::".join(config.encoding_lib.namespace)}}::Error; +using {{"::".join(config.encoding_lib.namespace)}}::Status; +using {{"::".join(config.encoding_lib.namespace)}}::span; +namespace cbor { +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::CBORTokenTag; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::CBORTokenizer; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeBinary; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeDouble; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFalse; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFromLatin1; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFromUTF16; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeIndefiniteLengthArrayStart; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeIndefiniteLengthMapStart; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeInt32; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeNull; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeStop; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeString8; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeTrue; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EnvelopeEncoder; +using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::InitialByteForEnvelope; +} // namespace cbor +{% endif %} + // Below are three parsing routines for CBOR, which cover enough // to roundtrip JSON messages. std::unique_ptr parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); @@ -178,7 +206,12 @@ std::unique_ptr parseMap( key = StringUtil::fromUTF8(key_span.data(), key_span.size()); tokenizer->Next(); } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) { - return nullptr; // STRING16 not supported yet. + span key_span = tokenizer->GetString16WireRep(); + if (key_span.size() & 1) return nullptr; // UTF16 is 2 byte multiple. + key = StringUtil::fromUTF16( + reinterpret_cast(key_span.data()), + key_span.size() / 2); + tokenizer->Next(); } else { // Error::CBOR_INVALID_MAP_KEY return nullptr; diff --git a/tools/inspector_protocol/lib/encoding_cpp.template b/tools/inspector_protocol/lib/encoding_cpp.template index 2fc7dd623fdcc3..d3646491140663 100644 --- a/tools/inspector_protocol/lib/encoding_cpp.template +++ b/tools/inspector_protocol/lib/encoding_cpp.template @@ -5,6 +5,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +{% if config.encoding_lib.header == "" %} #include #include @@ -192,11 +193,10 @@ namespace internals { // |type| is the major type as specified in RFC 7049 Section 2.1. // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size // (e.g. for BYTE_STRING). -// If successful, returns the number of bytes read. Otherwise returns -1. -// TODO(johannes): change return type to size_t and use 0 for error. -int8_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { +// If successful, returns the number of bytes read. Otherwise returns 0. +size_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { if (bytes.empty()) - return -1; + return 0; uint8_t initial_byte = bytes[0]; *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); @@ -210,32 +210,32 @@ int8_t ReadTokenStart(span bytes, MajorType* type, uint64_t* value) { if (additional_information == kAdditionalInformation1Byte) { // Values 24-255 are encoded with one initial byte, followed by the value. if (bytes.size() < 2) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 2; } if (additional_information == kAdditionalInformation2Bytes) { // Values 256-65535: 1 initial byte + 2 bytes payload. if (bytes.size() < 1 + sizeof(uint16_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 3; } if (additional_information == kAdditionalInformation4Bytes) { // 32 bit uint: 1 initial byte + 4 bytes payload. if (bytes.size() < 1 + sizeof(uint32_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 5; } if (additional_information == kAdditionalInformation8Bytes) { // 64 bit uint: 1 initial byte + 8 bytes payload. if (bytes.size() < 1 + sizeof(uint64_t)) - return -1; + return 0; *value = ReadBytesMostSignificantByteFirst(bytes.subspan(1)); return 9; } - return -1; + return 0; } // Writes the start of a token with |type|. The |value| may indicate the size, @@ -777,10 +777,10 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { SetToken(CBORTokenTag::NULL_VALUE, 1); return; case kExpectedConversionToBase64Tag: { // BINARY - const int8_t bytes_read = internals::ReadTokenStart( + const size_t bytes_read = internals::ReadTokenStart( bytes_.subspan(status_.pos + 1), &token_start_type_, &token_start_internal_value_); - if (bytes_read < 0 || token_start_type_ != MajorType::BYTE_STRING || + if (!bytes_read || token_start_type_ != MajorType::BYTE_STRING || token_start_internal_value_ > kMaxValidLength) { SetError(Error::CBOR_INVALID_BINARY); return; @@ -830,47 +830,49 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { return; } default: { - const int8_t token_start_length = internals::ReadTokenStart( + const size_t bytes_read = internals::ReadTokenStart( bytes_.subspan(status_.pos), &token_start_type_, &token_start_internal_value_); - const bool success = token_start_length >= 0; switch (token_start_type_) { case MajorType::UNSIGNED: // INT32. // INT32 is a signed int32 (int32 makes sense for the // inspector_protocol, it's not a CBOR limitation), so we check // against the signed max, so that the allowable values are // 0, 1, 2, ... 2^31 - 1. - if (!success || + if (!bytes_read || static_cast(std::numeric_limits::max()) < static_cast(token_start_internal_value_)) { SetError(Error::CBOR_INVALID_INT32); return; } - SetToken(CBORTokenTag::INT32, token_start_length); + SetToken(CBORTokenTag::INT32, bytes_read); return; case MajorType::NEGATIVE: { // INT32. // INT32 is a signed int32 (int32 makes sense for the - // inspector_protocol, it's not a CBOR limitation); in CBOR, - // the negative values for INT32 are represented as NEGATIVE, - // that is, -1 INT32 is represented as 1 << 5 | 0 (major type 1, - // additional info value 0). So here, we compute the INT32 value - // and then check it against the INT32 min. - int64_t actual_value = - -static_cast(token_start_internal_value_) - 1; - if (!success || actual_value < std::numeric_limits::min()) { + // inspector_protocol, it's not a CBOR limitation); in CBOR, the + // negative values for INT32 are represented as NEGATIVE, that is, -1 + // INT32 is represented as 1 << 5 | 0 (major type 1, additional info + // value 0). + // The represented allowed values range is -1 to -2^31. + // They are mapped into the encoded range of 0 to 2^31-1. + // We check the the payload in token_start_internal_value_ against + // that range (2^31-1 is also known as + // std::numeric_limits::max()). + if (!bytes_read || + static_cast(token_start_internal_value_) > + static_cast(std::numeric_limits::max())) { SetError(Error::CBOR_INVALID_INT32); return; } - SetToken(CBORTokenTag::INT32, token_start_length); + SetToken(CBORTokenTag::INT32, bytes_read); return; } case MajorType::STRING: { // STRING8. - if (!success || token_start_internal_value_ > kMaxValidLength) { + if (!bytes_read || token_start_internal_value_ > kMaxValidLength) { SetError(Error::CBOR_INVALID_STRING8); return; } - uint64_t token_byte_length = - token_start_internal_value_ + token_start_length; + uint64_t token_byte_length = token_start_internal_value_ + bytes_read; if (token_byte_length > remaining_bytes) { SetError(Error::CBOR_INVALID_STRING8); return; @@ -882,13 +884,12 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) { case MajorType::BYTE_STRING: { // STRING16. // Length must be divisible by 2 since UTF16 is 2 bytes per // character, hence the &1 check. - if (!success || token_start_internal_value_ > kMaxValidLength || + if (!bytes_read || token_start_internal_value_ > kMaxValidLength || token_start_internal_value_ & 1) { SetError(Error::CBOR_INVALID_STRING16); return; } - uint64_t token_byte_length = - token_start_internal_value_ + token_start_length; + uint64_t token_byte_length = token_start_internal_value_ + bytes_read; if (token_byte_length > remaining_bytes) { SetError(Error::CBOR_INVALID_STRING16); return; @@ -1864,7 +1865,7 @@ class JsonParser { // If the |Char| we're dealing with is really a byte, then // we have utf8 here, and we need to check for multibyte characters // and transcode them to utf16 (either one or two utf16 chars). - if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) { + if (sizeof(Char) == sizeof(uint8_t) && c > 0x7f) { // Inspect the leading byte to figure out how long the utf8 // byte sequence is; while doing this initialize |codepoint| // with the first few bits. @@ -1903,7 +1904,7 @@ class JsonParser { // Disallow overlong encodings for ascii characters, as these // would include " and other characters significant to JSON // string termination / control. - if (codepoint < 0x7f) + if (codepoint <= 0x7f) return false; // Invalid in UTF8, and can't be represented in UTF16 anyway. if (codepoint > 0x10ffff) @@ -2198,3 +2199,5 @@ Status ConvertJSONToCBOR(const Platform& platform, {% for namespace in config.protocol.namespace %} } // namespace {{namespace}} {% endfor %} + +{% endif %} diff --git a/tools/inspector_protocol/lib/encoding_h.template b/tools/inspector_protocol/lib/encoding_h.template index f1a52a1958a14d..2c6cfc10d594c2 100644 --- a/tools/inspector_protocol/lib/encoding_h.template +++ b/tools/inspector_protocol/lib/encoding_h.template @@ -5,6 +5,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +{% if config.encoding_lib.header == "" %} #ifndef {{"_".join(config.protocol.namespace)}}_encoding_h #define {{"_".join(config.protocol.namespace)}}_encoding_h @@ -435,7 +436,7 @@ Status AppendString8EntryToCBORMap(span string8_key, std::string* cbor); namespace internals { // Exposed only for writing tests. -int8_t ReadTokenStart(span bytes, +size_t ReadTokenStart(span bytes, cbor::MajorType* type, uint64_t* value); @@ -518,3 +519,4 @@ Status ConvertJSONToCBOR(const Platform& platform, } // namespace {{namespace}} {% endfor %} #endif // !defined({{"_".join(config.protocol.namespace)}}_encoding_h) +{% endif %} diff --git a/tools/license-builder.sh b/tools/license-builder.sh index 3d8e615a0e6169..6a3a6984aefd79 100755 --- a/tools/license-builder.sh +++ b/tools/license-builder.sh @@ -112,4 +112,7 @@ addlicense "uvwasi" "deps/uvwasi" "$(cat "${rootdir}"/deps/uvwasi/LICENSE)" addlicense "ngtcp2" "deps/ngtcp2/ngtcp2/" "$(cat "${rootdir}"/deps/ngtcp2/LICENSE_ngtcp2)" addlicense "nghttp3" "deps/ngtcp2/nghttp3/" "$(cat "${rootdir}"/deps/ngtcp2/LICENSE_nghttp3)" +addlicense "node-fs-extra" "lib/internal/fs/cp" \ + "$(curl -sL https://raw.githubusercontent.com/jprichardson/node-fs-extra/b34da2762a4865b025cac06d02d6a2f1f1027b65/LICENSE)" + mv "$tmplicense" "$licensefile" diff --git a/tools/lint-md.js b/tools/lint-md.js index 23a3e76a86f86e..23c4c03954a283 100644 --- a/tools/lint-md.js +++ b/tools/lint-md.js @@ -12,7 +12,7 @@ var tty = require('tty'); var fs$1 = require('fs'); var events = require('events'); var assert = require('assert'); -var require$$0$4 = require('url'); +var url = require('url'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } @@ -25,7 +25,6 @@ var tty__default = /*#__PURE__*/_interopDefaultLegacy(tty); var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$1); var events__default = /*#__PURE__*/_interopDefaultLegacy(events); var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); -var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$4); var vfileStatistics = statistics; @@ -39716,7 +39715,7 @@ const dependencies$1 = { remark: "^13.0.0", "remark-gfm": "^1.0.0", "remark-lint": "^8.0.0", - "remark-preset-lint-node": "^2.3.0", + "remark-preset-lint-node": "^3.0.0", "unified-args": "^8.1.0" }; const main = "dist/index.js"; @@ -39734,27 +39733,43 @@ var cli = { scripts: scripts$1 }; -var vfileLocation = factory$2; +/** + * @typedef {import('unist').Point} Point + * @typedef {import('vfile').VFile} VFile + * + * @typedef {Pick} PositionalPoint + * @typedef {Required} FullPoint + * @typedef {NonNullable} Offset + */ -function factory$2(file) { +/** + * Get transform functions for the given `document`. + * + * @param {string|Uint8Array|VFile} file + */ +function location(file) { var value = String(file); + /** @type {Array.} */ var indices = []; var search = /\r?\n|\r/g; - while (search.exec(value)) { + while (search.test(value)) { indices.push(search.lastIndex); } indices.push(value.length + 1); - return { - toPoint: offsetToPoint, - toPosition: offsetToPoint, - toOffset: pointToOffset - } + return {toPoint, toOffset} - // Get the line and column-based `point` for `offset` in the bound indices. - function offsetToPoint(offset) { + /** + * Get the line and column-based `point` for `offset` in the bound indices. + * Returns a point with `undefined` values when given invalid or out of bounds + * input. + * + * @param {Offset} offset + * @returns {FullPoint} + */ + function toPoint(offset) { var index = -1; if (offset > -1 && offset < indices[indices.length - 1]) { @@ -39763,23 +39778,35 @@ function factory$2(file) { return { line: index + 1, column: offset - (indices[index - 1] || 0) + 1, - offset: offset + offset } } } } - return {} + return {line: undefined, column: undefined, offset: undefined} } - // Get the `offset` for a line and column-based `point` in the bound - // indices. - function pointToOffset(point) { + /** + * Get the `offset` for a line and column-based `point` in the bound indices. + * Returns `-1` when given invalid or out of bounds input. + * + * @param {PositionalPoint} point + * @returns {Offset} + */ + function toOffset(point) { var line = point && point.line; var column = point && point.column; + /** @type {number} */ var offset; - if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + if ( + typeof line === 'number' && + typeof column === 'number' && + !Number.isNaN(line) && + !Number.isNaN(column) && + line - 1 in indices + ) { offset = (indices[line - 2] || 0) + column - 1 || 0; } @@ -39787,74 +39814,147 @@ function factory$2(file) { } } -var convert_1 = convert$3; - -function convert$3(test) { - if (test == null) { - return ok$1 - } - - if (typeof test === 'string') { - return typeFactory(test) - } - - if (typeof test === 'object') { - return 'length' in test ? anyFactory(test) : allFactory(test) - } +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ - if (typeof test === 'function') { - return test - } +const convert$3 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$1 + } - throw new Error('Expected function, string, or object as test') -} + if (typeof test === 'string') { + return typeFactory(test) + } -// Utility assert each property in `test` is represented in `node`, and each -// values are strictly equal. -function allFactory(test) { - return all + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory(test) : propsFactory(test) + } - function all(node) { - var key; + if (typeof test === 'function') { + return castFactory(test) + } - for (key in test) { - if (node[key] !== test[key]) return false + throw new Error('Expected function, string, or object as test') } - - return true - } -} - + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ function anyFactory(tests) { - var checks = []; - var index = -1; + /** @type {Array.} */ + const checks = []; + let index = -1; while (++index < tests.length) { checks[index] = convert$3(tests[index]); } - return any + return castFactory(any) - function any() { - var index = -1; + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; while (++index < checks.length) { - if (checks[index].apply(this, arguments)) { - return true - } + if (checks[index].call(this, ...parameters)) return true } return false } } -// Utility to convert a string into a function which checks a given node’s type -// for said string. -function typeFactory(test) { - return type +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory(check) { + return castFactory(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory(check) { + return castFactory(type) + /** + * @param {Node} node + */ function type(node) { - return Boolean(node && node.type === test) + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) } } @@ -39863,93 +39963,141 @@ function ok$1() { return true } -var color_1 = color$1; +/** + * @param {string} d + * @returns {string} + */ function color$1(d) { return '\u001B[33m' + d + '\u001B[39m' } -var unistUtilVisitParents = visitParents; - - - - -var CONTINUE = true; -var SKIP = 'skip'; -var EXIT = false; - -visitParents.CONTINUE = CONTINUE; -visitParents.SKIP = SKIP; -visitParents.EXIT = EXIT; - -function visitParents(tree, test, visitor, reverse) { - var step; - var is; - - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - is = convert_1(test); - step = reverse ? -1 : 1; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ - factory(tree, null, [])(); +/** + * Continue traversing as normal + */ +const CONTINUE = true; +/** + * Do not traverse this node’s children + */ +const SKIP = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT = false; - function factory(node, index, parents) { - var value = typeof node === 'object' && node !== null ? node : {}; - var name; +const visitParents = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-ignore no visitor given, so `visitor` is test. + visitor = test; + test = null; + } - if (typeof value.type === 'string') { - name = - typeof value.tagName === 'string' - ? value.tagName - : typeof value.name === 'string' - ? value.name - : undefined; + var is = convert$3(test); + var step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + var value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string} */ + var name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$1(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } - visit.displayName = - 'node (' + color_1(value.type + (name ? '<' + name + '>' : '')) + ')'; - } + return visit - return visit + function visit() { + /** @type {ActionTuple} */ + var result = []; + /** @type {ActionTuple} */ + var subresult; + /** @type {number} */ + var offset; + /** @type {Array.} */ + var grandparents; - function visit() { - var grandparents = parents.concat(node); - var result = []; - var subresult; - var offset; + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult(visitor(node, parents)); - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult(visitor(node, parents)); + if (result[0] === EXIT) { + return result + } + } - if (result[0] === EXIT) { - return result - } - } + if (node.children && result[0] !== SKIP) { + // @ts-ignore looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-ignore looks like a parent. + grandparents = parents.concat(node); - if (node.children && result[0] !== SKIP) { - offset = (reverse ? node.children.length : -1) + step; + // @ts-ignore looks like a parent. + while (offset > -1 && offset < node.children.length) { + subresult = factory(node.children[offset], offset, grandparents)(); - while (offset > -1 && offset < node.children.length) { - subresult = factory(node.children[offset], offset, grandparents)(); + if (subresult[0] === EXIT) { + return subresult + } - if (subresult[0] === EXIT) { - return subresult + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } } - offset = - typeof subresult[1] === 'number' ? subresult[1] : offset + step; + return result } } - - return result } - } -} + ); +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ function toResult(value) { - if (value !== null && typeof value === 'object' && 'length' in value) { + if (Array.isArray(value)) { return value } @@ -39960,93 +40108,197 @@ function toResult(value) { return [value] } -var unistUtilVisit = visit; - - - -var CONTINUE$1 = unistUtilVisitParents.CONTINUE; -var SKIP$1 = unistUtilVisitParents.SKIP; -var EXIT$1 = unistUtilVisitParents.EXIT; - -visit.CONTINUE = CONTINUE$1; -visit.SKIP = SKIP$1; -visit.EXIT = EXIT$1; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ -function visit(tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } +const visit = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - unistUtilVisitParents(tree, test, overload, reverse); + visitParents(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + var parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); - function overload(node, parents) { - var parent = parents[parents.length - 1]; - var index = parent ? parent.children.indexOf(node) : null; - return visitor(node, index, parent) - } -} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist').Point} Point + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * + * @typedef {OptionsWithoutReset|OptionsWithReset} Options + * @typedef {OptionsBaseFields & OptionsWithoutResetFields} OptionsWithoutReset + * @typedef {OptionsBaseFields & OptionsWithResetFields} OptionsWithReset + * + * @typedef OptionsWithoutResetFields + * @property {false} [reset] + * Whether to treat all messages as turned off initially. + * @property {string[]} [disable] + * List of `ruleId`s to turn off. + * + * @typedef OptionsWithResetFields + * @property {true} reset + * Whether to treat all messages as turned off initially. + * @property {string[]} [enable] + * List of `ruleId`s to initially turn on. + * + * @typedef OptionsBaseFields + * @property {string} name + * Name of markers that can control the message sources. + * + * For example, `{name: 'alpha'}` controls `alpha` markers: + * + * ```html + * + * ``` + * @property {MarkerParser} marker + * Parse a possible marker to a comment marker object (Marker). + * If the marker isn't a marker, should return `null`. + * @property {Test} [test] + * Test for possible markers + * @property {string[]} [known] + * List of allowed `ruleId`s. When given a warning is shown + * when someone tries to control an unknown rule. + * + * For example, `{name: 'alpha', known: ['bravo']}` results in a warning if + * `charlie` is configured: + * + * ```html + * + * ``` + * @property {string|string[]} [source] + * Sources that can be controlled with `name` markers. + * Defaults to `name`. + * + * @callback MarkerParser + * Parse a possible comment marker node to a Marker. + * @param {Node} node + * Node to parse + * + * @typedef Marker + * A comment marker. + * @property {string} name + * Name of marker. + * @property {string} attributes + * Value after name. + * @property {Record} parameters + * Parsed attributes. + * @property {Node} node + * Reference to given node. + * + * @typedef Mark + * @property {Point|undefined} point + * @property {boolean} state + */ -var unifiedMessageControl = messageControl; +const own$6 = {}.hasOwnProperty; +/** + * @type {import('unified').Plugin<[Options]>} + * @returns {(tree: Node, file: VFile) => void} + */ function messageControl(options) { - var settings = options || {}; - var enable = settings.enable || []; - var disable = settings.disable || []; - var sources = settings.source; - var reset = settings.reset; - - if (!settings.name) { - throw new Error('Expected `name` in `options`, got `' + settings.name + '`') + if (!options || typeof options !== 'object' || !options.name) { + throw new Error( + 'Expected `name` in `options`, got `' + (options || {}).name + '`' + ) } - if (!settings.marker) { + if (!options.marker) { throw new Error( - 'Expected `marker` in `options`, got `' + settings.marker + '`' + 'Expected `marker` in `options`, got `' + options.marker + '`' ) } - if (!sources) { - sources = [settings.name]; - } else if (typeof sources === 'string') { - sources = [sources]; - } + const enable = 'enable' in options && options.enable ? options.enable : []; + const disable = 'disable' in options && options.disable ? options.disable : []; + let reset = options.reset; + const sources = + typeof options.source === 'string' + ? [options.source] + : options.source || [options.name]; return transformer + /** + * @param {Node} tree + * @param {VFile} file + */ function transformer(tree, file) { - var toOffset = vfileLocation(file).toOffset; - var initial = !reset; - var gaps = detectGaps(tree, file); - var scope = {}; - var globals = []; + const toOffset = location(file).toOffset; + const initial = !reset; + const gaps = detectGaps(tree, file); + /** @type {Record} */ + const scope = {}; + /** @type {Mark[]} */ + const globals = []; - unistUtilVisit(tree, settings.test, visitor); + visit(tree, options.test, visitor); - file.messages = file.messages.filter(filter); + file.messages = file.messages.filter((m) => filter(m)); + /** + * @param {Node} node + * @param {number|null} position + * @param {Parent|null} parent + */ function visitor(node, position, parent) { - var mark = settings.marker(node); - var ruleIds; - var verb; - var pos; - var tail; - var index; - var ruleId; + /** @type {Marker|null} */ + const mark = options.marker(node); - if (!mark || mark.name !== settings.name) { + if (!mark || mark.name !== options.name) { return } - ruleIds = mark.attributes.split(/\s/g); - verb = ruleIds.shift(); - pos = mark.node.position && mark.node.position.start; - tail = - parent.children[position + 1] && - parent.children[position + 1].position && - parent.children[position + 1].position.end; - index = -1; + const ruleIds = mark.attributes.split(/\s/g); + const point = mark.node.position && mark.node.position.start; + const next = + (parent && position !== null && parent.children[position + 1]) || + undefined; + const tail = (next && next.position && next.position.end) || undefined; + let index = -1; + + /** @type {string} */ + // @ts-expect-error: we’ll check for unknown values next. + const verb = ruleIds.shift(); if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { file.fail( @@ -40059,12 +40311,12 @@ function messageControl(options) { } // Apply to all rules. - if (ruleIds.length) { + if (ruleIds.length > 0) { while (++index < ruleIds.length) { - ruleId = ruleIds[index]; + const ruleId = ruleIds[index]; if (isKnown(ruleId, verb, mark.node)) { - toggle(pos, verb === 'enable', ruleId); + toggle(point, verb === 'enable', ruleId); if (verb === 'ignore') { toggle(tail, true, ruleId); @@ -40072,20 +40324,23 @@ function messageControl(options) { } } } else if (verb === 'ignore') { - toggle(pos, false); + toggle(point, false); toggle(tail, true); } else { - toggle(pos, verb === 'enable'); + toggle(point, verb === 'enable'); reset = verb !== 'enable'; } } + /** + * @param {VFileMessage} message + * @returns {boolean} + */ function filter(message) { - var gapIndex = gaps.length; - var pos; + let gapIndex = gaps.length; // Keep messages from a different source. - if (!message.source || sources.indexOf(message.source) === -1) { + if (!message.source || !sources.includes(message.source)) { return true } @@ -40100,41 +40355,55 @@ function messageControl(options) { } // Check whether the warning is inside a gap. - pos = toOffset(message); + // @ts-expect-error: we just normalized `null` to `number`s. + const offset = toOffset(message); while (gapIndex--) { - if (gaps[gapIndex].start <= pos && gaps[gapIndex].end > pos) { + if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { return false } } // Check whether allowed by specific and global states. return ( - check(message, scope[message.ruleId], message.ruleId) && + (!message.ruleId || + check(message, scope[message.ruleId], message.ruleId)) && check(message, globals) ) } - // Helper to check (and possibly warn) if a `ruleId` is unknown. - function isKnown(ruleId, verb, pos) { - var result = settings.known ? settings.known.indexOf(ruleId) !== -1 : true; + /** + * Helper to check (and possibly warn) if a `ruleId` is unknown. + * + * @param {string} ruleId + * @param {string} verb + * @param {Node} node + * @returns {boolean} + */ + function isKnown(ruleId, verb, node) { + const result = options.known ? options.known.includes(ruleId) : true; if (!result) { file.message( 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", - pos + node ); } return result } - // Get the latest state of a rule. - // When without `ruleId`, gets global state. + /** + * Get the latest state of a rule. + * When without `ruleId`, gets global state. + * + * @param {string|undefined} ruleId + * @returns {boolean} + */ function getState(ruleId) { - var ranges = ruleId ? scope[ruleId] : globals; + const ranges = ruleId ? scope[ruleId] : globals; - if (ranges && ranges.length) { + if (ranges && ranges.length > 0) { return ranges[ranges.length - 1].state } @@ -40142,71 +40411,102 @@ function messageControl(options) { return !reset } - return reset ? enable.indexOf(ruleId) > -1 : disable.indexOf(ruleId) < 0 + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) } - // Handle a rule. - function toggle(pos, state, ruleId) { - var markers = ruleId ? scope[ruleId] : globals; - var previousState; + /** + * Handle a rule. + * + * @param {Point|undefined} point + * @param {boolean} state + * @param {string|undefined} [ruleId] + * @returns {void} + */ + function toggle(point, state, ruleId) { + let markers = ruleId ? scope[ruleId] : globals; if (!markers) { markers = []; - scope[ruleId] = markers; + scope[String(ruleId)] = markers; } - previousState = getState(ruleId); + const previousState = getState(ruleId); if (state !== previousState) { - markers.push({state: state, position: pos}); + markers.push({state, point}); } // Toggle all known rules. if (!ruleId) { for (ruleId in scope) { - toggle(pos, state, ruleId); + if (own$6.call(scope, ruleId)) { + toggle(point, state, ruleId); + } } } } - // Check all `ranges` for `message`. + /** + * Check all `ranges` for `message`. + * + * @param {VFileMessage} message + * @param {Mark[]|undefined} ranges + * @param {string|undefined} [ruleId] + * @returns {boolean} + */ function check(message, ranges, ruleId) { - // Check the state at the message’s position. - var index = ranges && ranges.length; + if (ranges && ranges.length > 0) { + // Check the state at the message’s position. + let index = ranges.length; - while (index--) { - if ( - ranges[index].position && - ranges[index].position.line && - ranges[index].position.column && - (ranges[index].position.line < message.line || - (ranges[index].position.line === message.line && - ranges[index].position.column <= message.column)) - ) { - return ranges[index].state === true + while (index--) { + const range = ranges[index]; + + if ( + message.line && + message.column && + range.point && + range.point.line && + range.point.column && + (range.point.line < message.line || + (range.point.line === message.line && + range.point.column <= message.column)) + ) { + return range.state === true + } } } // The first marker ocurred after the first message, so we check the // initial state. if (!ruleId) { - return initial || reset + return Boolean(initial || reset) } - return reset ? enable.indexOf(ruleId) > -1 : disable.indexOf(ruleId) < 0 + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) } } } -// Detect gaps in `tree`. +/** + * Detect gaps in `tree`. + * + * @param {Node} tree + * @param {VFile} file + */ function detectGaps(tree, file) { - var lastNode = tree.children[tree.children.length - 1]; - var offset = 0; - var gaps = []; - var gap; + /** @type {Node[]} */ + // @ts-expect-error: fine. + const children = tree.children || []; + const lastNode = children[children.length - 1]; + /** @type {[number, number][]} */ + const gaps = []; + let offset = 0; + /** @type {boolean|undefined} */ + let gap; // Find all gaps. - unistUtilVisit(tree, one); + visit(tree, one); // Get the end of the document. // This detects if the last node was the last node. @@ -40217,33 +40517,45 @@ function detectGaps(tree, file) { lastNode.position && lastNode.position.end && offset === lastNode.position.end.offset && - trim(file.toString().slice(offset)) !== '' + file.toString().slice(offset).trim() !== '' ) { update(); update( - tree && tree.position && tree.position.end && tree.position.end.offset - 1 + tree && + tree.position && + tree.position.end && + tree.position.end.offset && + tree.position.end.offset - 1 ); } return gaps + /** + * @param {Node} node + */ function one(node) { update(node.position && node.position.start && node.position.start.offset); - if (!node.children) { + if (!('children' in node)) { update(node.position && node.position.end && node.position.end.offset); } } - // Detect a new position. + /** + * Detect a new position. + * + * @param {number|undefined} [latest] + * @returns {void} + */ function update(latest) { if (latest === null || latest === undefined) { gap = true; } else if (offset < latest) { if (gap) { - gaps.push({start: offset, end: latest}); - gap = null; + gaps.push([offset, latest]); + gap = undefined; } offset = latest; @@ -40251,630 +40563,626 @@ function detectGaps(tree, file) { } } -function trim(value) { - return value.replace(/^\s+|\s+$/g, '') -} - -var mdastCommentMarker = marker$1; - -var whiteSpaceExpression = /\s+/g; - -var parametersExpression = /\s+([-a-z0-9_]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi; +/** + * @typedef {string|number|boolean} MarkerParameterValue + * @typedef {Object.} MarkerParameters + * + * @typedef HtmlNode + * @property {'html'} type + * @property {string} value + * + * @typedef CommentNode + * @property {'comment'} type + * @property {string} value + * + * @typedef Marker + * @property {string} name + * @property {string} attributes + * @property {MarkerParameters|null} parameters + * @property {HtmlNode|CommentNode} node + */ -var commentExpression = /\s*([a-zA-Z0-9-]+)(\s+([\s\S]*))?\s*/; +var commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; var markerExpression = new RegExp( '(\\s*\\s*)' ); -// Parse a comment marker. -function marker$1(node) { - var type; - var value; +/** + * Parse a comment marker. + * @param {unknown} node + * @returns {Marker|null} + */ +function commentMarker(node) { + /** @type {RegExpMatchArray} */ var match; - var params; - - if (!node) { - return null - } - - type = node.type; - - if (type !== 'html' && type !== 'comment') { - return null - } - - value = node.value; - match = value.match(type === 'comment' ? commentExpression : markerExpression); - - if (!match || match[0].length !== value.length) { - return null - } - - match = match.slice(node.type === 'comment' ? 1 : 2); + /** @type {number} */ + var offset; + /** @type {MarkerParameters} */ + var parameters; - params = parameters(match[1] || ''); + if ( + node && + typeof node === 'object' && + // @ts-ignore hush + (node.type === 'html' || node.type === 'comment') + ) { + // @ts-ignore hush + match = node.value.match( + // @ts-ignore hush + node.type === 'comment' ? commentExpression : markerExpression + ); - if (!params) { - return null + // @ts-ignore hush + if (match && match[0].length === node.value.length) { + // @ts-ignore hush + offset = node.type === 'comment' ? 1 : 2; + parameters = parseParameters(match[offset + 1] || ''); + + if (parameters) { + return { + name: match[offset], + attributes: match[offset + 2] || '', + parameters, + // @ts-ignore hush + node + } + } + } } - return { - name: match[0], - attributes: match[2] || '', - parameters: params, - node: node - } + return null } -// Parse `value` into an object. -function parameters(value) { - var attributes = {}; - var rest = value.replace(parametersExpression, replacer); +/** + * Parse `value` into an object. + * + * @param {string} value + * @returns {MarkerParameters|null} + */ +function parseParameters(value) { + /** @type {MarkerParameters} */ + var parameters = {}; - return rest.replace(whiteSpaceExpression, '') ? null : attributes + return value + .replace( + /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, + replacer + ) + .replace(/\s+/g, '') + ? null + : parameters + /** + * @param {string} _ + * @param {string} $1 + * @param {string} $2 + * @param {string} $3 + * @param {string} $4 + */ // eslint-disable-next-line max-params - function replacer($0, $1, $2, $3, $4) { - var result = $2 || $3 || $4 || ''; + function replacer(_, $1, $2, $3, $4) { + /** @type {MarkerParameterValue} */ + var value = $2 || $3 || $4 || ''; - if (result === 'true' || result === '') { - result = true; - } else if (result === 'false') { - result = false; - } else if (!isNaN(result)) { - result = Number(result); + if (value === 'true' || value === '') { + value = true; + } else if (value === 'false') { + value = false; + } else if (!Number.isNaN(Number(value))) { + value = Number(value); } - attributes[$1] = result; + parameters[$1] = value; return '' } } -var remarkMessageControl = messageControl$1; +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('vfile').VFile} VFile + * @typedef {import('unified-message-control')} MessageControl + * @typedef {Omit|Omit} Options + */ -var test = [ +const test = [ 'html', // Comments are `html` nodes in mdast. 'comment' // In MDX, comments have their own node. ]; -function messageControl$1(options) { - return unifiedMessageControl(Object.assign({marker: mdastCommentMarker, test: test}, options)) +/** + * Plugin to enable, disable, and ignore messages. + * + * @type {import('unified').Plugin<[Options], Root>} + * @returns {(node: Root, file: VFile) => void} + */ +function remarkMessageControl(options) { + return messageControl( + Object.assign({marker: commentMarker, test}, options) + ) } -var remarkLint = lint; +/** + * @typedef {import('mdast').Root} Root + */ -// `remark-lint`. -// This adds support for ignoring stuff from messages (``). -// All rules are in their own packages and presets. -function lint() { +/** + * The core plugin for `remark-lint`. + * This adds support for ignoring stuff from messages (``). + * All rules are in their own packages and presets. + * + * @type {import('unified').Plugin} + */ +function remarkLint() { this.use(lintMessageControl); } +/** @type {import('unified').Plugin} */ function lintMessageControl() { return remarkMessageControl({name: 'lint', source: 'remark-lint'}) } /** - * An Array.prototype.slice.call(arguments) alternative + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware * - * @param {Object} args something with a length - * @param {Number} slice - * @param {Number} sliceEnd - * @api public + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline */ -var sliced = function (args, slice, sliceEnd) { - var ret = []; - var len = args.length; +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$1(middleware, callback) { + /** @type {boolean} */ + let called; - if (0 === len) return ret; + return wrapped - var start = slice < 0 - ? Math.max(0, slice + len) - : slice || 0; + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; - if (sliceEnd !== undefined) { - len = sliceEnd < 0 - ? sliceEnd + len - : sliceEnd; - } + if (fnExpectsCallback) { + parameters.push(done); + } - while (len-- > start) { - ret[len - start] = args[len]; - } + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - return ret; -}; + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } -/** - * slice() reference. - */ + return done(exception) + } -var slice$4 = Array.prototype.slice; + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } -/** - * Expose `co`. - */ + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } -var co_1 = co; + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} /** - * Wrap the given generator `fn` and - * return a thunk. + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * @param {Function} fn - * @return {Function} - * @api public + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ -function co(fn) { - var isGenFun = isGeneratorFunction(fn); +const primitives = new Set(['string', 'number', 'boolean']); - return function (done) { - var ctx = this; +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; - // in toThunk() below we invoke co() - // with a generator, so optimize for - // this case - var gen = fn; + Object.defineProperty(plugin, 'name', {value: id}); - // we only need to parse the arguments - // if gen is a generator function. - if (isGenFun) { - var args = slice$4.call(arguments), len = args.length; - var hasCallback = len && 'function' == typeof args[len - 1]; - done = hasCallback ? args.pop() : error; - gen = fn.apply(this, args); - } else { - done = done || error; - } + return plugin - next(); + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce(ruleId, raw); - // #92 - // wrap the callback in a setImmediate - // so that any of its errors aren't caught by `co` - function exit(err, res) { - setImmediate(function(){ - done.call(ctx, err, res); - }); - } + if (!severity) return - function next(err, res) { - var ret; + const fatal = severity === 2; - // multiple args - if (arguments.length > 2) res = slice$4.call(arguments, 1); + return (tree, file, next) => { + let index = file.messages.length - 1; - // error - if (err) { - try { - ret = gen.throw(err); - } catch (e) { - return exit(e); - } - } + wrap$1(rule, (error) => { + const messages = file.messages; - // ok - if (!err) { - try { - ret = gen.next(res); - } catch (e) { - return exit(e); + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} } - } - - // done - if (ret.done) return exit(null, ret.value); - // normalize - ret.value = toThunk(ret.value, ctx); - - // run - if ('function' == typeof ret.value) { - var called = false; - try { - ret.value.call(ctx, function(){ - if (called) return; - called = true; - next.apply(ctx, arguments); - }); - } catch (e) { - setImmediate(function(){ - if (called) return; - called = true; - next(e); - }); + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); } - return; - } - // invalid - next(new TypeError('You may only yield a function, promise, generator, array, or object, ' - + 'but the following was passed: "' + String(ret.value) + '"')); + next(); + })(tree, file, options); } } } /** - * Convert `obj` into a normalized thunk. + * Coerce a value to a severity--options tuple. * - * @param {Mixed} obj - * @param {Mixed} ctx - * @return {Function} - * @api private + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} */ +function coerce(name, value) { + /** @type {unknown[]} */ + let result; -function toThunk(obj, ctx) { - - if (isGeneratorFunction(obj)) { - return co(obj.call(ctx)); + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; } - if (isGenerator(obj)) { - return co(obj); - } + let level = result[0]; - if (isPromise(obj)) { - return promiseToThunk(obj); + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } } - if ('function' == typeof obj) { - return obj; + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) } - if (isObject$3(obj) || Array.isArray(obj)) { - return objectToThunk.call(ctx, obj); - } + result[0] = level; - return obj; + // @ts-expect-error: it’s now a valid tuple. + return result } /** - * Convert an object of yieldables to a thunk. + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module final-newline + * @fileoverview + * Warn when a line feed at the end of a file is missing. + * Empty files are allowed. * - * @param {Object} obj - * @return {Function} - * @api private - */ - -function objectToThunk(obj){ - var ctx = this; - var isArray = Array.isArray(obj); - - return function(done){ - var keys = Object.keys(obj); - var pending = keys.length; - var results = isArray - ? new Array(pending) // predefine the array length - : new obj.constructor(); - var finished; - - if (!pending) { - setImmediate(function(){ - done(null, results); - }); - return; - } - - // prepopulate object keys to preserve key ordering - if (!isArray) { - for (var i = 0; i < pending; i++) { - results[keys[i]] = undefined; - } - } - - for (var i = 0; i < keys.length; i++) { - run(obj[keys[i]], keys[i]); - } - - function run(fn, key) { - if (finished) return; - try { - fn = toThunk(fn, ctx); - - if ('function' != typeof fn) { - results[key] = fn; - return --pending || done(null, results); - } - - fn.call(ctx, function(err, res){ - if (finished) return; - - if (err) { - finished = true; - return done(err); - } - - results[key] = res; - --pending || done(null, results); - }); - } catch (err) { - finished = true; - done(err); - } - } - } -} - -/** - * Convert `promise` to a thunk. + * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. * - * @param {Object} promise - * @return {Function} - * @api private - */ - -function promiseToThunk(promise) { - return function(fn){ - promise.then(function(res) { - fn(null, res); - }, fn); - } -} - -/** - * Check if `obj` is a promise. + * ## Fix * - * @param {Object} obj - * @return {Boolean} - * @api private - */ - -function isPromise(obj) { - return obj && 'function' == typeof obj.then; -} - -/** - * Check if `obj` is a generator. + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * always adds a final line feed to files. * - * @param {Mixed} obj - * @return {Boolean} - * @api private - */ - -function isGenerator(obj) { - return obj && 'function' == typeof obj.next && 'function' == typeof obj.throw; -} - -/** - * Check if `obj` is a generator function. + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. * - * @param {Mixed} obj - * @return {Boolean} - * @api private - */ - -function isGeneratorFunction(obj) { - return obj && obj.constructor && 'GeneratorFunction' == obj.constructor.name; -} - -/** - * Check for plain object. + * ## Example * - * @param {Mixed} val - * @return {Boolean} - * @api private - */ - -function isObject$3(val) { - return val && Object == val.constructor; -} - -/** - * Throw `err` in a new stack. + * ##### `ok.md` * - * This is used when co() is invoked - * without supplying a callback, which - * should only be for demonstrational - * purposes. + * ###### In * - * @param {Error} err - * @api private - */ - -function error(err) { - if (!err) return; - setImmediate(function(){ - throw err; - }); -} - -/** - * Module Dependencies + * Note: `␊` represents LF. + * + * ```markdown + * Alpha␊ + * ``` + * + * ###### Out + * + * No messages. + * + * ##### `not-ok.md` + * + * ###### In + * + * Note: The below file does not have a final newline. + * + * ```markdown + * Bravo + * ``` + * + * ###### Out + * + * ```text + * 1:1: Missing newline character at end of file + * ``` */ -var noop$2 = function(){}; +const remarkLintFinalNewline = lintRule( + 'remark-lint:final-newline', + /** @type {import('unified-lint-rule').Rule} */ + (_, file) => { + const value = String(file); + const last = value.length - 1; + if (last > -1 && value.charAt(last) !== '\n') { + file.message('Missing newline character at end of file'); + } + } +); /** - * Export `wrapped` + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline */ -var wrapped_1 = wrapped; - /** - * Wrap a function to support - * sync, async, and gen functions. + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. * - * @param {Function} fn - * @return {Function} - * @api public + * @param {Middleware} middleware + * @param {Callback} callback */ +function wrap$2(middleware, callback) { + /** @type {boolean} */ + let called; -function wrapped(fn) { - function wrap() { - var args = sliced(arguments); - var last = args[args.length - 1]; - var ctx = this; + return wrapped - // done - var done = typeof last == 'function' ? args.pop() : noop$2; + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; - // nothing - if (!fn) { - return done.apply(ctx, [null].concat(args)); + if (fnExpectsCallback) { + parameters.push(done); } - // generator - if (generator(fn)) { - return co_1(fn).apply(ctx, args.concat(done)); - } + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - // async - if (fn.length > args.length) { - // NOTE: this only handles uncaught synchronous errors - try { - return fn.apply(ctx, args.concat(done)); - } catch (e) { - return done(e); + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception } + + return done(exception) } - // sync - return sync$5(fn, done).apply(ctx, args); + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } } - return wrap; -} - -/** - * Wrap a synchronous function execution. - * - * @param {Function} fn - * @param {Function} done - * @return {Function} - * @api private - */ - -function sync$5(fn, done) { - return function () { - var ret; - - try { - ret = fn.apply(this, arguments); - } catch (err) { - return done(err); + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); } + } - if (promise(ret)) { - ret.then(function (value) { done(null, value); }, done); - } else { - ret instanceof Error ? done(ret) : done(null, ret); - } + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); } } /** - * Is `value` a generator? + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * @param {Mixed} value - * @return {Boolean} - * @api private + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ -function generator(value) { - return value - && value.constructor - && 'GeneratorFunction' == value.constructor.name; -} - +const primitives$1 = new Set(['string', 'number', 'boolean']); /** - * Is `value` a promise? - * - * @param {Mixed} value - * @return {Boolean} - * @api private + * @param {string} id + * @param {Rule} rule */ +function lintRule$1(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; -function promise(value) { - return value && 'function' == typeof value.then; -} - -var unifiedLintRule = factory$3; - -function factory$3(id, rule) { - var parts = id.split(':'); - var source = parts[0]; - var ruleId = parts[1]; - var fn = wrapped_1(rule); - - /* istanbul ignore if - possibly useful if externalised later. */ - if (!ruleId) { - ruleId = source; - source = null; - } - - attacher.displayName = id; + Object.defineProperty(plugin, 'name', {value: id}); - return attacher + return plugin - function attacher(raw) { - var config = coerce(ruleId, raw); - var severity = config[0]; - var options = config[1]; - var fatal = severity === 2; + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$1(ruleId, raw); - return severity ? transformer : undefined + if (!severity) return - function transformer(tree, file, next) { - var index = file.messages.length; + const fatal = severity === 2; - fn(tree, file, options, done); + return (tree, file, next) => { + let index = file.messages.length - 1; - function done(err) { - var messages = file.messages; - var message; + wrap$2(rule, (error) => { + const messages = file.messages; // Add the error, if not already properly added. - /* istanbul ignore if - only happens for incorrect plugins */ - if (err && messages.indexOf(err) === -1) { + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { try { - file.fail(err); - } catch (_) {} + file.fail(error); + } catch {} } - while (index < messages.length) { - message = messages[index]; - message.ruleId = ruleId; - message.source = source; - message.fatal = fatal; - - index++; + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); } next(); - } + })(tree, file, options); } } } -// Coerce a value to a severity--options tuple. -function coerce(name, value) { - var def = 1; - var result; - var level; +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$1(name, value) { + /** @type {unknown[]} */ + let result; - /* istanbul ignore if - Handled by unified in v6.0.0 */ if (typeof value === 'boolean') { result = [value]; - } else if (value == null) { - result = [def]; + } else if (value === null || value === undefined) { + result = [1]; } else if ( - typeof value === 'object' && - (typeof value[0] === 'number' || - typeof value[0] === 'boolean' || - typeof value[0] === 'string') + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$1.has(typeof value[0]) ) { - result = value.concat(); + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; } else { result = [1, value]; } - level = result[0]; + let level = result[0]; if (typeof level === 'boolean') { level = level ? 1 : 0; @@ -40891,7 +41199,7 @@ function coerce(name, value) { } } - if (level < 0 || level > 2) { + if (typeof level !== 'number' || level < 0 || level > 2) { throw new Error( 'Incorrect severity `' + level + @@ -40904,74 +41212,10 @@ function coerce(name, value) { result[0] = level; + // @ts-expect-error: it’s now a valid tuple. return result } -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-newline - * @fileoverview - * Warn when a line feed at the end of a file is missing. - * Empty files are allowed. - * - * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * always adds a final line feed to files. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * ## Example - * - * ##### `ok.md` - * - * ###### In - * - * Note: `␊` represents LF. - * - * ```markdown - * Alpha␊ - * ``` - * - * ###### Out - * - * No messages. - * - * ##### `not-ok.md` - * - * ###### In - * - * Note: The below file does not have a final newline. - * - * ```markdown - * Bravo - * ``` - * - * ###### Out - * - * ```text - * 1:1: Missing newline character at end of file - * ``` - */ - - - -var remarkLintFinalNewline = unifiedLintRule('remark-lint:final-newline', finalNewline); - -function finalNewline(tree, file) { - var contents = String(file); - var last = contents.length - 1; - - if (last > -1 && contents.charAt(last) !== '\n') { - file.message('Missing newline character at end of file'); - } -} - /* global define */ var pluralize = createCommonjsModule(function (module, exports) { @@ -41473,1568 +41717,1915 @@ var pluralize = createCommonjsModule(function (module, exports) { }); }); -var unistUtilGenerated = generated; - -function generated(node) { - return ( - !node || - !node.position || - !node.position.start || - !node.position.start.line || - !node.position.start.column || - !node.position.end || - !node.position.end.line || - !node.position.end.column - ) -} - /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-bullet-indent - * @fileoverview - * Warn when list item bullets are indented. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all indentation before bullets. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md"} - * - * Paragraph. - * - * * List item - * * List item - * - * @example {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * ·* List item - * ·* List item + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent * - * @example {"name": "not-ok.md", "label": "output"} + * @typedef {string} Type + * @typedef {Object} Props * - * 3:2: Incorrect indentation before bullet: remove 1 space - * 4:2: Incorrect indentation before bullet: remove 1 space + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test */ +const convert$4 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$2 + } + if (typeof test === 'string') { + return typeFactory$1(test) + } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$1(test) : propsFactory$1(test) + } + if (typeof test === 'function') { + return castFactory$1(test) + } + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$1(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; -var remarkLintListItemBulletIndent = unifiedLintRule( - 'remark-lint:list-item-bullet-indent', - listItemBulletIndent -); - -function listItemBulletIndent(tree, file) { - unistUtilVisit(tree, 'list', visitor); - - function visitor(list, _, grandparent) { - list.children.forEach(visitItems); - - function visitItems(item) { - var indent; - var reason; + while (++index < tests.length) { + checks[index] = convert$4(tests[index]); + } - if ( - grandparent && - grandparent.type === 'root' && - !unistUtilGenerated(item) && - !unistUtilGenerated(grandparent) - ) { - indent = item.position.start.column - grandparent.position.start.column; + return castFactory$1(any) - if (indent) { - reason = - 'Incorrect indentation before bullet: remove ' + - indent + - ' ' + - pluralize('space', indent); + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; - file.message(reason, item.position.start); - } - } + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true } + + return false } } -var start$1 = factory$4('start'); -var end = factory$4('end'); +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$1(check) { + return castFactory$1(all) -var unistUtilPosition = position$1; + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; -position$1.start = start$1; -position$1.end = end; + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } -function position$1(node) { - return {start: start$1(node), end: end(node)} + return true + } } -function factory$4(type) { - point.displayName = type; +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$1(check) { + return castFactory$1(type) - return point + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} - function point(node) { - var point = (node && node.position && node.position[type]) || {}; +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$1(check) { + return assertion - return { - line: point.line || null, - column: point.column || null, - offset: isNaN(point.offset) ? null : point.offset - } + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) } } +// Utility to return true. +function ok$2() { + return true +} + /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-indent - * @fileoverview - * Warn when the spacing between a list item’s bullet and its content violates - * a given style. - * - * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is - * seen the same way across vendors. - * This can be configured with the - * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) - * option. - * This rule’s `'space'` option is named `'1'` there. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md"} - * - * *···List - * ····item. - * - * Paragraph. - * - * 11.·List - * ····item. - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example {"name": "ok.md", "setting": "mixed"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example {"name": "ok.md", "setting": "space"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *·List - * ··item. - * - * *·List - * ··item. - * - * @example {"name": "not-ok.md", "setting": "space", "label": "input"} - * - * *···List - * ····item. - * - * @example {"name": "not-ok.md", "setting": "space", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example {"name": "not-ok.md", "setting": "tab-size", "label": "input"} - * - * *·List - * ··item. - * - * @example {"name": "not-ok.md", "setting": "tab-size", "label": "output"} - * - * 1:3: Incorrect list-item indent: add 2 spaces - * - * @example {"name": "not-ok.md", "setting": "mixed", "label": "input"} - * - * *···List item. - * - * @example {"name": "not-ok.md", "setting": "mixed", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example {"name": "not-ok.md", "setting": "💩", "label": "output", "config": {"positionless": true}} - * - * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` + * @param {string} d + * @returns {string} */ +function color$2(d) { + return '\u001B[33m' + d + '\u001B[39m' +} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ +/** + * Continue traversing as normal + */ +const CONTINUE$1 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$1 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$1 = false; +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + const is = convert$4(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$2(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + return visit + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; -var remarkLintListItemIndent = unifiedLintRule('remark-lint:list-item-indent', listItemIndent); - -var start$2 = unistUtilPosition.start; - -var styles$1 = {'tab-size': true, mixed: true, space: true}; - -function listItemIndent(tree, file, option) { - var contents = String(file); - var preferred = typeof option === 'string' ? option : 'tab-size'; - - if (styles$1[preferred] !== true) { - file.fail( - 'Incorrect list-item indent style `' + - preferred + - "`: use either `'tab-size'`, `'space'`, or `'mixed'`" - ); - } - - unistUtilVisit(tree, 'list', visitor); - - function visitor(node) { - var spread = node.spread || node.loose; - - if (!unistUtilGenerated(node)) { - node.children.forEach(visitItem); - } - - function visitItem(item) { - var head = item.children[0]; - var final = start$2(head); - var marker; - var bulletSize; - var style; - var diff; - var reason; - var abs; + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$1(visitor(node, parents)); - marker = contents - .slice(start$2(item).offset, final.offset) - .replace(/\[[x ]?]\s*$/i, ''); + if (result[0] === EXIT$1) { + return result + } + } - bulletSize = marker.replace(/\s+$/, '').length; + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$1) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); - style = - preferred === 'tab-size' || (preferred === 'mixed' && spread) - ? Math.ceil(bulletSize / 4) * 4 - : bulletSize + 1; + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); - if (marker.length !== style) { - diff = style - marker.length; - abs = Math.abs(diff); + if (subresult[0] === EXIT$1) { + return subresult + } - reason = - 'Incorrect list-item indent: ' + - (diff > 0 ? 'add' : 'remove') + - ' ' + - abs + - ' ' + - pluralize('space', abs); + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } - file.message(reason, final); + return result + } } } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$1(value) { + if (Array.isArray(value)) { + return value } -} -var mdastUtilToString$1 = toString$4; + if (typeof value === 'number') { + return [CONTINUE$1, value] + } -// Get the text content of a node. -// Prefer the node’s plain-text fields, otherwise serialize its children, -// and if the given value is an array, serialize the nodes in it. -function toString$4(node) { - return ( - (node && - (node.value || - node.alt || - node.title || - ('children' in node && all$1(node.children)) || - ('length' in node && all$1(node)))) || - '' - ) + return [value] } -function all$1(values) { - var result = []; - var length = values.length; - var index = -1; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ - while (++index < length) { - result[index] = toString$4(values[index]); - } +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - return result.join('') -} + visitParents$1(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); /** * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT - * @module no-auto-link-without-protocol + * @module list-item-bullet-indent * @fileoverview - * Warn for autolinks without protocol. - * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) - * characters. + * Warn when list item bullets are indented. * * ## Fix * * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds a protocol where needed. + * removes all indentation before bullets. * * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) * on how to automatically fix warnings for this rule. * - * @example {"name": "ok.md"} + * @example + * {"name": "ok.md"} * - * - * + * Paragraph. * - * Most Markdown vendors don’t recognize the following as a link: - * + * * List item + * * List item * - * @example {"name": "not-ok.md", "label": "input"} + * @example + * {"name": "not-ok.md", "label": "input"} * - * + * Paragraph. * - * @example {"name": "not-ok.md", "label": "output"} + * ·* List item + * ·* List item * - * 1:1-1:14: All automatic links must start with a protocol + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:2: Incorrect indentation before bullet: remove 1 space + * 4:2: Incorrect indentation before bullet: remove 1 space */ +const remarkLintListItemBulletIndent = lintRule$1( + 'remark-lint:list-item-bullet-indent', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'list', (list, _, grandparent) => { + let index = -1; + while (++index < list.children.length) { + const item = list.children[index]; + if ( + grandparent && + grandparent.type === 'root' && + grandparent.position && + typeof grandparent.position.start.column === 'number' && + item.position && + typeof item.position.start.column === 'number' + ) { + const indent = + item.position.start.column - grandparent.position.start.column; + if (indent) { + file.message( + 'Incorrect indentation before bullet: remove ' + + indent + + ' ' + + pluralize('space', indent), + item.position.start + ); + } + } + } + }); + } +); +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$3(middleware, callback) { + /** @type {boolean} */ + let called; -var remarkLintNoAutoLinkWithoutProtocol = unifiedLintRule( - 'remark-lint:no-auto-link-without-protocol', - noAutoLinkWithoutProtocol -); - -var start$3 = unistUtilPosition.start; -var end$1 = unistUtilPosition.end; + return wrapped -// Protocol expression. -// See: . -var protocol = /^[a-z][a-z+.-]+:\/?/i; + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; -var reason = 'All automatic links must start with a protocol'; + if (fnExpectsCallback) { + parameters.push(done); + } -function noAutoLinkWithoutProtocol(tree, file) { - unistUtilVisit(tree, 'link', visitor); + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - function visitor(node) { - var children; + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } - if (!unistUtilGenerated(node)) { - children = node.children; + return done(exception) + } - if ( - start$3(node).column === start$3(children[0]).column - 1 && - end$1(node).column === end$1(children[children.length - 1]).column + 1 && - !protocol.test(mdastUtilToString$1(node)) - ) { - file.message(reason, node); + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); } } } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-blockquote-without-marker - * @fileoverview - * Warn when blank lines without `>` (greater than) markers are found in a - * block quote. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds markers to every line in a block quote. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md"} + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * > Foo… - * > …bar… - * > …baz. - * - * @example {"name": "ok-tabs.md"} - * - * >»Foo… - * >»…bar… - * >»…baz. - * - * @example {"name": "not-ok.md", "label": "input"} - * - * > Foo… - * …bar… - * > …baz. - * - * @example {"name": "not-ok.md", "label": "output"} - * - * 2:1: Missing marker in block quote + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple * - * @example {"name": "not-ok-tabs.md", "label": "input"} - * - * >»Foo… - * »…bar… - * …baz. - * - * @example {"name": "not-ok-tabs.md", "label": "output"} - * - * 2:1: Missing marker in block quote - * 3:1: Missing marker in block quote + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ +const primitives$2 = new Set(['string', 'number', 'boolean']); +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$2(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + Object.defineProperty(plugin, 'name', {value: id}); + return plugin + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$2(ruleId, raw); + if (!severity) return -var remarkLintNoBlockquoteWithoutMarker = unifiedLintRule( - 'remark-lint:no-blockquote-without-marker', - noBlockquoteWithoutMarker -); - -var reason$1 = 'Missing marker in block quote'; - -function noBlockquoteWithoutMarker(tree, file) { - var contents = String(file); - var location = vfileLocation(file); - - unistUtilVisit(tree, 'blockquote', visitor); + const fatal = severity === 2; - function onquotedchild(node) { - var line; - var end; - var column; - var offset; + return (tree, file, next) => { + let index = file.messages.length - 1; - if (node.type === 'paragraph' && !unistUtilGenerated(node)) { - line = unistUtilPosition.start(node).line; - end = unistUtilPosition.end(node).line; - column = unistUtilPosition.start(node).column; + wrap$3(rule, (error) => { + const messages = file.messages; - // Skip past the first line. - while (++line <= end) { - offset = location.toOffset({line: line, column: column}); + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - if (/>[\t ]+$/.test(contents.slice(offset - 5, offset))) { - continue + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); } - // Roughly here. - file.message(reason$1, {line: line, column: column - 2}); - } + next(); + })(tree, file, options); } } - - function visitor(node) { - node.children.forEach(onquotedchild); - } } -var mdastUtilToString$2 = toString$5; +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$2(name, value) { + /** @type {unknown[]} */ + let result; -// Get the text content of a node. -// Prefer the node’s plain-text fields, otherwise serialize its children, -// and if the given value is an array, serialize the nodes in it. -function toString$5(node) { - return ( - (node && - (node.value || - node.alt || - node.title || - ('children' in node && all$2(node.children)) || - ('length' in node && all$2(node)))) || - '' - ) -} + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$2.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } -function all$2(values) { - var result = []; - var length = values.length; - var index = -1; + let level = result[0]; - while (++index < length) { - result[index] = toString$5(values[index]); + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } } - return result.join('') + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-literal-urls - * @fileoverview - * Warn for literal URLs in text. - * URLs are treated as links in some Markdown vendors, but not in others. - * To make sure they are always linked, wrap them in `<` (less than) and `>` - * (greater than). - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * never creates literal URLs and always uses `<` (less than) and `>` - * (greater than). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md"} + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent * - * - * - * @example {"name": "not-ok.md", "label": "input"} - * - * http://foo.bar/baz + * @typedef {string} Type + * @typedef {Object} Props * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:19: Don’t use literal URLs without angle brackets + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test */ +const convert$5 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$3 + } + + if (typeof test === 'string') { + return typeFactory$2(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$2(test) : propsFactory$2(test) + } + if (typeof test === 'function') { + return castFactory$2(test) + } + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$2(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + while (++index < tests.length) { + checks[index] = convert$5(tests[index]); + } + return castFactory$2(any) + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; -var remarkLintNoLiteralUrls = unifiedLintRule('remark-lint:no-literal-urls', noLiteralURLs); + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } -var start$4 = unistUtilPosition.start; -var end$2 = unistUtilPosition.end; -var mailto = 'mailto:'; -var reason$2 = 'Don’t use literal URLs without angle brackets'; + return false + } +} -function noLiteralURLs(tree, file) { - unistUtilVisit(tree, 'link', visitor); +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$2(check) { + return castFactory$2(all) - function visitor(node) { - var children = node.children; - var value = mdastUtilToString$2(node); + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; - if ( - !unistUtilGenerated(node) && - start$4(node).column === start$4(children[0]).column && - end$2(node).column === end$2(children[children.length - 1]).column && - (node.url === mailto + value || node.url === value) - ) { - file.message(reason$2, node); + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false } + + return true } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module ordered-list-marker-style - * @fileoverview - * Warn when the list item marker style of ordered lists violate a given style. - * - * Options: `'consistent'`, `'.'`, or `')'`, default: `'consistent'`. - * - * `'consistent'` detects the first used list style and warns when subsequent - * lists use different styles. - * - * Note: `)` is only supported in CommonMark. - * - * @example {"name": "ok.md"} - * - * 1. Foo - * - * - * 1. Bar - * - * Unordered lists are not affected by this rule. - * - * * Foo - * - * @example {"name": "ok.md", "setting": "."} - * - * 1. Foo - * - * 2. Bar - * - * @example {"name": "ok.md", "setting": ")", "config": {"commonmark": true}} - * - * - * - * 1) Foo - * - * 2) Bar - * - * @example {"name": "not-ok.md", "label": "input", "config": {"commonmark": true}} - * - * 1. Foo - * - * 2) Bar - * - * @example {"name": "not-ok.md", "label": "output"} + * Utility to convert a string into a function which checks a given node’s type + * for said string. * - * 3:1-3:8: Marker style should be `.` - * - * @example {"name": "not-ok.md", "label": "output", "setting": "💩", "config": {"positionless": true}} - * - * 1:1: Incorrect ordered list item marker style `💩`: use either `'.'` or `')'` + * @param {Type} check + * @returns {AssertAnything} */ +function typeFactory$2(check) { + return castFactory$2(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$2(check) { + return assertion + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} +// Utility to return true. +function ok$3() { + return true +} +/** + * @param {string} d + * @returns {string} + */ +function color$3(d) { + return '\u001B[33m' + d + '\u001B[39m' +} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ -var remarkLintOrderedListMarkerStyle = unifiedLintRule( - 'remark-lint:ordered-list-marker-style', - orderedListMarkerStyle -); +/** + * Continue traversing as normal + */ +const CONTINUE$2 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$2 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$2 = false; -var start$5 = unistUtilPosition.start; +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$2 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } -var styles$2 = { - ')': true, - '.': true, - null: true -}; + const is = convert$5(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$3(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } -function orderedListMarkerStyle(tree, file, option) { - var contents = String(file); - var preferred = - typeof option !== 'string' || option === 'consistent' ? null : option; + return visit - if (styles$2[preferred] !== true) { - file.fail( - 'Incorrect ordered list item marker style `' + - preferred + - "`: use either `'.'` or `')'`" - ); - } + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; - unistUtilVisit(tree, 'list', visitor); + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$2(visitor(node, parents)); - function visitor(node) { - var children = node.children; - var length = node.ordered ? children.length : 0; - var index = -1; - var marker; - var child; + if (result[0] === EXIT$2) { + return result + } + } - while (++index < length) { - child = children[index]; + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$2) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); - if (!unistUtilGenerated(child)) { - marker = contents - .slice(start$5(child).offset, start$5(child.children[0]).offset) - .replace(/\s|\d/g, '') - .replace(/\[[x ]?]\s*$/i, ''); + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$2) { + return subresult + } - if (preferred) { - if (marker !== preferred) { - file.message('Marker style should be `' + preferred + '`', child); + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } } - } else { - preferred = marker; + + return result } } } - } -} + ); /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module hard-break-spaces - * @fileoverview - * Warn when too many spaces are used to create a hard break. - * - * @example {"name": "ok.md"} - * - * Lorem ipsum·· - * dolor sit amet - * - * @example {"name": "not-ok.md", "label": "input"} - * - * Lorem ipsum··· - * dolor sit amet. - * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:12-2:1: Use two spaces for hard line breaks + * @param {VisitorResult} value + * @returns {ActionTuple} */ +function toResult$2(value) { + if (Array.isArray(value)) { + return value + } + if (typeof value === 'number') { + return [CONTINUE$2, value] + } + return [value] +} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$2 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - -var remarkLintHardBreakSpaces = unifiedLintRule('remark-lint:hard-break-spaces', hardBreakSpaces); - -var reason$3 = 'Use two spaces for hard line breaks'; - -function hardBreakSpaces(tree, file) { - var contents = String(file); - - unistUtilVisit(tree, 'break', visitor); - - function visitor(node) { - var value; - - if (!unistUtilGenerated(node)) { - value = contents - .slice(unistUtilPosition.start(node).offset, unistUtilPosition.end(node).offset) - .split('\n', 1)[0] - .replace(/\r$/, ''); - - if (value.length > 2) { - file.message(reason$3, node); + visitParents$2(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) } } - } -} + ); /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-duplicate-definitions - * @fileoverview - * Warn when duplicate definitions are found. - * - * @example {"name": "ok.md"} - * - * [foo]: bar - * [baz]: qux - * - * @example {"name": "not-ok.md", "label": "input"} + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point * - * [foo]: bar - * [foo]: qux + * @typedef {Partial} PointLike * - * @example {"name": "not-ok.md", "label": "output"} + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] * - * 2:1-2:11: Do not use definitions with the same identifier (1:1) + * @typedef {Object} NodeLike + * @property {PositionLike} [position] */ +var pointStart = point$1('start'); +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$1(type) { + return point + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; - - - -var remarkLintNoDuplicateDefinitions = unifiedLintRule( - 'remark-lint:no-duplicate-definitions', - noDuplicateDefinitions -); - -var reason$4 = 'Do not use definitions with the same identifier'; - -function noDuplicateDefinitions(tree, file) { - var map = {}; - - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], check); - - function check(node) { - var identifier; - var duplicate; - - if (!unistUtilGenerated(node)) { - identifier = node.identifier; - duplicate = map[identifier]; - - if (duplicate && duplicate.type) { - file.message( - reason$4 + ' (' + unistUtilStringifyPosition(unistUtilPosition.start(duplicate)) + ')', - node - ); - } - - map[identifier] = node; + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null } } } -var mdastUtilHeadingStyle = style; - -function style(node, relative) { - var last = node.children[node.children.length - 1]; - var depth = node.depth; - var pos = node && node.position && node.position.end; - var final = last && last.position && last.position.end; - - if (!pos) { - return null - } - - // This can only occur for `'atx'` and `'atx-closed'` headings. - // This might incorrectly match `'atx'` headings with lots of trailing white - // space as an `'atx-closed'` heading. - if (!last) { - if (pos.column - 1 <= depth * 2) { - return consolidate(depth, relative) - } - - return 'atx-closed' - } - - if (final.line + 1 === pos.line) { - return 'setext' - } - - if (final.column + depth < pos.column) { - return 'atx-closed' - } - - return consolidate(depth, relative) -} +/** + * @typedef {Object} PointLike + * @property {number} [line] + * @property {number} [column] + * @property {number} [offset] + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ -// Get the probable style of an atx-heading, depending on preferred style. -function consolidate(depth, relative) { - return depth < 3 - ? 'atx' - : relative === 'atx' || relative === 'setext' - ? relative - : null +/** + * Check if `node` is *generated*. + * + * @param {NodeLike} [node] + * @returns {boolean} + */ +function generated(node) { + return ( + !node || + !node.position || + !node.position.start || + !node.position.start.line || + !node.position.start.column || + !node.position.end || + !node.position.end.line || + !node.position.end.column + ) } /** * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT - * @module no-heading-content-indent + * @module list-item-indent * @fileoverview - * Warn when content of headings is indented. + * Warn when the spacing between a list item’s bullet and its content violates + * a given style. + * + * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. * * ## Fix * * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all unneeded padding around content in headings. + * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is + * seen the same way across vendors. + * This can be configured with the + * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) + * option. + * This rule’s `'space'` option is named `'1'` there. * * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) * on how to automatically fix warnings for this rule. * - * @example {"name": "ok.md"} + * @example + * {"name": "ok.md"} * - * #·Foo + * *···List + * ····item. * - * ## Bar·## + * Paragraph. * - * ##·Baz + * 11.·List + * ····item. * - * Setext headings are not affected. + * Paragraph. * - * Baz - * === + * *···List + * ····item. * - * @example {"name": "not-ok.md", "label": "input"} + * *···List + * ····item. * - * #··Foo + * @example + * {"name": "ok.md", "setting": "mixed"} * - * ## Bar··## + * *·List item. * - * ##··Baz + * Paragraph. + * + * 11.·List item * - * @example {"name": "not-ok.md", "label": "output"} + * Paragraph. * - * 1:4: Remove 1 space before this heading’s content - * 3:7: Remove 1 space after this heading’s content - * 5:7: Remove 1 space before this heading’s content + * *···List + * ····item. + * + * *···List + * ····item. * - * @example {"name": "empty-heading.md"} + * @example + * {"name": "ok.md", "setting": "space"} * - * #·· + * *·List item. + * + * Paragraph. + * + * 11.·List item + * + * Paragraph. + * + * *·List + * ··item. + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "input"} + * + * *···List + * ····item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "input"} + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "output"} + * + * 1:3: Incorrect list-item indent: add 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "input"} + * + * *···List item. + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true} + * + * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` */ +const remarkLintListItemIndent = lintRule$2( + 'remark-lint:list-item-indent', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'tab-size') => { + const value = String(file); + + if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') { + file.fail( + 'Incorrect list-item indent style `' + + option + + "`: use either `'tab-size'`, `'space'`, or `'mixed'`" + ); + } + + visit$2(tree, 'list', (node) => { + if (generated(node)) return + const spread = node.spread; + let index = -1; + while (++index < node.children.length) { + const item = node.children[index]; + const head = item.children[0]; + const final = pointStart(head); + const marker = value + .slice(pointStart(item).offset, final.offset) + .replace(/\[[x ]?]\s*$/i, ''); + const bulletSize = marker.replace(/\s+$/, '').length; + const style = + option === 'tab-size' || (option === 'mixed' && spread) + ? Math.ceil(bulletSize / 4) * 4 + : bulletSize + 1; + if (marker.length !== style) { + const diff = style - marker.length; + const abs = Math.abs(diff); -var remarkLintNoHeadingContentIndent = unifiedLintRule( - 'remark-lint:no-heading-content-indent', - noHeadingContentIndent + file.message( + 'Incorrect list-item indent: ' + + (diff > 0 ? 'add' : 'remove') + + ' ' + + abs + + ' ' + + pluralize('space', abs), + final + ); + } + } + }); + } ); -var start$6 = unistUtilPosition.start; -var end$3 = unistUtilPosition.end; +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$4(middleware, callback) { + /** @type {boolean} */ + let called; -function noHeadingContentIndent(tree, file) { - unistUtilVisit(tree, 'heading', visitor); + return wrapped - function visitor(node) { - var depth; - var children; - var type; - var head; - var final; - var diff; - var reason; - var abs; + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; - if (unistUtilGenerated(node)) { - return + if (fnExpectsCallback) { + parameters.push(done); } - depth = node.depth; - children = node.children; - type = mdastUtilHeadingStyle(node, 'atx'); - - if (type === 'atx' || type === 'atx-closed') { - head = start$6(children[0]).column; + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - // Ignore empty headings. - if (!head) { - return + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception } - diff = head - start$6(node).column - 1 - depth; - - if (diff) { - abs = Math.abs(diff); - - reason = - 'Remove ' + - abs + - ' ' + - pluralize('space', abs) + - ' before this heading’s content'; - - file.message(reason, start$6(children[0])); - } + return done(exception) } - // Closed ATX headings always must have a space between their content and - // the final hashes, thus, there is no `add x spaces`. - if (type === 'atx-closed') { - final = end$3(children[children.length - 1]); - diff = end$3(node).column - final.column - 1 - depth; - - if (diff) { - reason = - 'Remove ' + - diff + - ' ' + - pluralize('space', diff) + - ' after this heading’s content'; - - file.message(reason, final); + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); } } } -} - -var mdastUtilToString$3 = toString$6; - -// Get the text content of a node. -// Prefer the node’s plain-text fields, otherwise serialize its children, -// and if the given value is an array, serialize the nodes in it. -function toString$6(node) { - return ( - (node && - (node.value || - node.alt || - node.title || - ('children' in node && all$3(node.children)) || - ('length' in node && all$3(node)))) || - '' - ) -} - -function all$3(values) { - var result = []; - var length = values.length; - var index = -1; - while (++index < length) { - result[index] = toString$6(values[index]); + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } } - return result.join('') + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-inline-padding - * @fileoverview - * Warn when phrasing content is padded with spaces between their markers and - * content. - * - * Warns for emphasis, strong, delete, image, and link. - * - * @example {"name": "ok.md"} - * - * Alpha [bravo](http://echo.fox/trot) - * - * @example {"name": "not-ok.md", "label": "input"} - * - * Alpha [ bravo ](http://echo.fox/trot) + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * @example {"name": "not-ok.md", "label": "output"} + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple * - * 1:7-1:38: Don’t pad `link` with inner spaces + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ +const primitives$3 = new Set(['string', 'number', 'boolean']); + +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$3(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + Object.defineProperty(plugin, 'name', {value: id}); + return plugin + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$3(ruleId, raw); + if (!severity) return -var remarkLintNoInlinePadding = unifiedLintRule('remark-lint:no-inline-padding', noInlinePadding); + const fatal = severity === 2; -function noInlinePadding(tree, file) { - // Note: `emphasis`, `strong`, `delete` (GFM) can’t have padding anymore - // since CM. - unistUtilVisit(tree, ['link', 'linkReference'], visitor); + return (tree, file, next) => { + let index = file.messages.length - 1; - function visitor(node) { - var contents; + wrap$4(rule, (error) => { + const messages = file.messages; - if (!unistUtilGenerated(node)) { - contents = mdastUtilToString$3(node); + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - if ( - contents.charAt(0) === ' ' || - contents.charAt(contents.length - 1) === ' ' - ) { - file.message('Don’t pad `' + node.type + '` with inner spaces', node); - } + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); } } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-image - * @fileoverview - * Warn when shortcut reference images are used. - * - * Shortcut references render as images when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create an image from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `!\[foo]`. - * - * @example {"name": "ok.md"} - * - * ![foo][] - * - * [foo]: http://foo.bar/baz.png - * - * @example {"name": "not-ok.md", "label": "input"} - * - * ![foo] - * - * [foo]: http://foo.bar/baz.png + * Coerce a value to a severity--options tuple. * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:7: Use the trailing [] on reference images + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} */ +function coerce$3(name, value) { + /** @type {unknown[]} */ + let result; + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$3.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + let level = result[0]; + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } -var remarkLintNoShortcutReferenceImage = unifiedLintRule( - 'remark-lint:no-shortcut-reference-image', - noShortcutReferenceImage -); - -var reason$5 = 'Use the trailing [] on reference images'; - -function noShortcutReferenceImage(tree, file) { - unistUtilVisit(tree, 'imageReference', visitor); + result[0] = level; - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$5, node); - } - } + // @ts-expect-error: it’s now a valid tuple. + return result } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-link - * @fileoverview - * Warn when shortcut reference links are used. - * - * Shortcut references render as links when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create a link from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `\[foo]`. - * - * @example {"name": "ok.md"} - * - * [foo][] + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent * - * [foo]: http://foo.bar/baz - * - * @example {"name": "not-ok.md", "label": "input"} - * - * [foo] + * @typedef {string} Type + * @typedef {Object} Props * - * [foo]: http://foo.bar/baz - * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Use the trailing `[]` on reference links + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test */ +const convert$6 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$4 + } + + if (typeof test === 'string') { + return typeFactory$3(test) + } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$3(test) : propsFactory$3(test) + } + if (typeof test === 'function') { + return castFactory$3(test) + } + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$3(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; -var remarkLintNoShortcutReferenceLink = unifiedLintRule( - 'remark-lint:no-shortcut-reference-link', - noShortcutReferenceLink -); + while (++index < tests.length) { + checks[index] = convert$6(tests[index]); + } -var reason$6 = 'Use the trailing `[]` on reference links'; + return castFactory$3(any) -function noShortcutReferenceLink(tree, file) { - unistUtilVisit(tree, 'linkReference', visitor); + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$6, node); + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true } - } -} - -var collapseWhiteSpace = collapse; -// `collapse(' \t\nbar \nbaz\t') // ' bar baz '` -function collapse(value) { - return String(value).replace(/\s+/g, ' ') + return false + } } /** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-undefined-references - * @fileoverview - * Warn when references to undefined definitions are found. - * - * Options: `Object`, optional. - * - * The object can have an `allow` field, set to an array of strings that may - * appear between `[` and `]`, but that should not be treated as link - * identifiers. - * - * @example {"name": "ok.md"} - * - * [foo][] - * - * Just a [ bracket. - * - * Typically, you’d want to use escapes (with a backslash: \\) to escape what - * could turn into a \[reference otherwise]. - * - * Just two braces can’t link: []. - * - * [foo]: https://example.com - * - * @example {"name": "ok-allow.md", "setting": {"allow": ["...", "…"]}} - * - * > Eliding a portion of a quoted passage […] is acceptable. - * - * @example {"name": "not-ok.md", "label": "input"} - * - * [bar] - * - * [baz][] - * - * [text][qux] - * - * Spread [over - * lines][] - * - * > in [a - * > block quote][] - * - * [asd][a - * - * Can include [*emphasis*]. - * - * Multiple pairs: [a][b][c]. + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Found reference to undefined definition - * 3:1-3:8: Found reference to undefined definition - * 5:1-5:12: Found reference to undefined definition - * 7:8-8:9: Found reference to undefined definition - * 10:6-11:17: Found reference to undefined definition - * 13:1-13:6: Found reference to undefined definition - * 15:13-15:25: Found reference to undefined definition - * 17:17-17:23: Found reference to undefined definition - * 17:23-17:26: Found reference to undefined definition + * @param {Props} check + * @returns {AssertAnything} */ +function propsFactory$3(check) { + return castFactory$3(all) + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + return true + } +} +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$3(check) { + return castFactory$3(type) + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$3(check) { + return assertion + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} -var remarkLintNoUndefinedReferences = unifiedLintRule( - 'remark-lint:no-undefined-references', - noUndefinedReferences -); - -var reason$7 = 'Found reference to undefined definition'; - -// The identifier is upcased to avoid naming collisions with fields inherited -// from `Object.prototype`. -// If `Object.create(null)` was used in place of `{}`, downcasing would work -// equally well. -function normalize$2(s) { - return collapseWhiteSpace(s.toUpperCase()) +// Utility to return true. +function ok$4() { + return true } -function noUndefinedReferences(tree, file, option) { - var contents = String(file); - var location = vfileLocation(file); - var lineEnding = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; - var allow = ((option || {}).allow || []).map(normalize$2); - var map = {}; - - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], mark); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], find); - unistUtilVisit(tree, ['paragraph', 'heading'], findInPhrasing); - - function mark(node) { - if (!unistUtilGenerated(node)) { - map[normalize$2(node.identifier)] = true; - } - } - - function find(node) { - if ( - !unistUtilGenerated(node) && - !(normalize$2(node.identifier) in map) && - allow.indexOf(normalize$2(node.identifier)) === -1 - ) { - file.message(reason$7, node); - } - } - - function findInPhrasing(node) { - var ranges = []; - - unistUtilVisit(node, onchild); - - ranges.forEach(handleRange); - - return unistUtilVisit.SKIP - - function onchild(child) { - var start; - var end; - var source; - var lines; - var last; - var index; - var match; - var line; - var code; - var lineIndex; - var next; - var range; - - // Ignore the node itself. - if (child === node) return - - // Can’t have links in links, so reset ranges. - if (child.type === 'link' || child.type === 'linkReference') { - ranges = []; - return unistUtilVisit.SKIP - } - - // Enter non-text. - if (child.type !== 'text') return - - start = unistUtilPosition.start(child).offset; - end = unistUtilPosition.end(child).offset; - - // Bail if there’s no positional info. - if (!end) return unistUtilVisit.EXIT +/** + * @param {string} d + * @returns {string} + */ +function color$4(d) { + return '\u001B[33m' + d + '\u001B[39m' +} - source = contents.slice(start, end); - lines = [[start, '']]; - last = 0; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ - lineEnding.lastIndex = 0; - match = lineEnding.exec(source); +/** + * Continue traversing as normal + */ +const CONTINUE$3 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$3 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$3 = false; - while (match) { - index = match.index; - lines[lines.length - 1][1] = source.slice(last, index); - last = index + match[0].length; - lines.push([start + last, '']); - match = lineEnding.exec(source); +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$3 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; } - lines[lines.length - 1][1] = source.slice(last); - lineIndex = -1; + const is = convert$6(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$4(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } - while (++lineIndex < lines.length) { - line = lines[lineIndex][1]; - index = 0; + return visit - while (index < line.length) { - code = line.charCodeAt(index); + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; - // Skip past escaped brackets. - if (code === 92) { - next = line.charCodeAt(index + 1); - index++; + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$3(visitor(node, parents)); - if (next === 91 || next === 93) { - index++; + if (result[0] === EXIT$3) { + return result } } - // Opening bracket. - else if (code === 91) { - ranges.push([lines[lineIndex][0] + index]); - index++; - } - // Close bracket. - else if (code === 93) { - // No opening. - if (ranges.length === 0) { - index++; - } else if (line.charCodeAt(index + 1) === 91) { - index++; - // Collapsed or full. - range = ranges.pop(); - range.push(lines[lineIndex][0] + index); + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$3) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); - // This is the end of a reference already. - if (range.length === 4) { - handleRange(range); - range = []; - } + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); - range.push(lines[lineIndex][0] + index); - ranges.push(range); - index++; - } else { - index++; + if (subresult[0] === EXIT$3) { + return subresult + } - // Shortcut or typical end of a reference. - range = ranges.pop(); - range.push(lines[lineIndex][0] + index); - handleRange(range); + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; } } - // Anything else. - else { - index++; - } + + return result } } } + ); - function handleRange(range) { - var offset; +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$3(value) { + if (Array.isArray(value)) { + return value + } - if (range.length === 1) return - if (range.length === 3) range.length = 2; + if (typeof value === 'number') { + return [CONTINUE$3, value] + } - // No need to warn for just `[]`. - if (range.length === 2 && range[0] + 2 === range[1]) return + return [value] +} - offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ - find({ - identifier: contents - .slice(range[0 + offset] + 1, range[1 + offset] - 1) - .replace(lineEnding, ' '), - position: { - start: location.toPosition(range[0]), - end: location.toPosition(range[range.length - 1]) - } - }); +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$3 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$3(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } } - } -} + ); /** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-unused-definitions - * @fileoverview - * Warn when unused definitions are found. + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point * - * @example {"name": "ok.md"} + * @typedef {Partial} PointLike * - * [foo][] - * - * [foo]: https://example.com - * - * @example {"name": "not-ok.md", "label": "input"} + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] * - * [bar]: https://example.com - * - * @example {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:27: Found unused definition + * @typedef {Object} NodeLike + * @property {PositionLike} [position] */ +var pointStart$1 = point$2('start'); +var pointEnd = point$2('end'); +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$2(type) { + return point + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; - -var remarkLintNoUnusedDefinitions = unifiedLintRule('remark-lint:no-unused-definitions', noUnusedDefinitions); - -var reason$8 = 'Found unused definition'; - -function noUnusedDefinitions(tree, file) { - var map = {}; - var identifier; - var entry; - - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], find); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], mark); - - for (identifier in map) { - entry = map[identifier]; - - if (!entry.used) { - file.message(reason$8, entry.node); - } - } - - function find(node) { - if (!unistUtilGenerated(node)) { - map[node.identifier.toUpperCase()] = {node: node, used: false}; - } - } - - function mark(node) { - var info = map[node.identifier.toUpperCase()]; - - if (!unistUtilGenerated(node) && info) { - info.used = true; + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null } } } /** - * @fileoverview - * remark preset to configure `remark-lint` with settings that prevent - * mistakes or syntaxes that do not work correctly across vendors. + * @typedef Options + * @property {boolean} [includeImageAlt=true] */ -var plugins$1 = [ - remarkLint, - // Unix compatibility. - remarkLintFinalNewline, - // Rendering across vendors differs greatly if using other styles. - remarkLintListItemBulletIndent, - [remarkLintListItemIndent, 'tab-size'], - // Differs or unsupported across vendors. - remarkLintNoAutoLinkWithoutProtocol, - remarkLintNoBlockquoteWithoutMarker, - remarkLintNoLiteralUrls, - [remarkLintOrderedListMarkerStyle, '.'], - // Mistakes. - remarkLintHardBreakSpaces, - remarkLintNoDuplicateDefinitions, - remarkLintNoHeadingContentIndent, - remarkLintNoInlinePadding, - remarkLintNoShortcutReferenceImage, - remarkLintNoShortcutReferenceLink, - remarkLintNoUndefinedReferences, - remarkLintNoUnusedDefinitions -]; - -var remarkPresetLintRecommended = { - plugins: plugins$1 -}; - -var mdastUtilToString$4 = toString$7; +/** + * Get the text content of a node. + * Prefer the node’s plain-text fields, otherwise serialize its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} node + * @param {Options} [options] + * @returns {string} + */ +function toString$4(node, options) { + var {includeImageAlt = true} = options || {}; + return one$1(node, includeImageAlt) +} -// Get the text content of a node. -// Prefer the node’s plain-text fields, otherwise serialize its children, -// and if the given value is an array, serialize the nodes in it. -function toString$7(node) { +/** + * @param {unknown} node + * @param {boolean} includeImageAlt + * @returns {string} + */ +function one$1(node, includeImageAlt) { return ( (node && + typeof node === 'object' && + // @ts-ignore looks like a literal. (node.value || - node.alt || - node.title || - ('children' in node && all$4(node.children)) || - ('length' in node && all$4(node)))) || + // @ts-ignore looks like an image. + (includeImageAlt ? node.alt : '') || + // @ts-ignore looks like a parent. + ('children' in node && all$1(node.children, includeImageAlt)) || + (Array.isArray(node) && all$1(node, includeImageAlt)))) || '' ) } -function all$4(values) { +/** + * @param {Array.} values + * @param {boolean} includeImageAlt + * @returns {string} + */ +function all$1(values, includeImageAlt) { + /** @type {Array.} */ var result = []; - var length = values.length; var index = -1; - while (++index < length) { - result[index] = toString$7(values[index]); + while (++index < values.length) { + result[index] = one$1(values[index], includeImageAlt); } return result.join('') @@ -43044,552 +43635,752 @@ function all$4(values) { * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT - * @module blockquote-indentation + * @module no-auto-link-without-protocol * @fileoverview - * Warn when block quotes are indented too much or too little. - * - * Options: `number` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used indentation and will warn when - * other block quotes use a different indentation. - * - * @example {"name": "ok.md", "setting": 4} - * - * > Hello - * - * Paragraph. - * - * > World - * - * @example {"name": "ok.md", "setting": 2} - * - * > Hello + * Warn for autolinks without protocol. + * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) + * characters. * - * Paragraph. + * ## Fix * - * > World + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds a protocol where needed. * - * @example {"name": "not-ok.md", "label": "input"} + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. * - * > Hello + * @example + * {"name": "ok.md"} * - * Paragraph. + * + * * - * > World + * Most Markdown vendors don’t recognize the following as a link: + * * - * Paragraph. + * @example + * {"name": "not-ok.md", "label": "input"} * - * > World + * * - * @example {"name": "not-ok.md", "label": "output"} + * @example + * {"name": "not-ok.md", "label": "output"} * - * 5:3: Remove 1 space between block quote and content - * 9:3: Add 1 space between block quote and content + * 1:1-1:14: All automatic links must start with a protocol */ +// Protocol expression. +// See: . +const protocol = /^[a-z][a-z+.-]+:\/?/i; +const remarkLintNoAutoLinkWithoutProtocol = lintRule$3( + 'remark-lint:no-auto-link-without-protocol', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$3(tree, 'link', (node) => { + if ( + !generated(node) && + pointStart$1(node).column === pointStart$1(node.children[0]).column - 1 && + pointEnd(node).column === + pointEnd(node.children[node.children.length - 1]).column + 1 && + !protocol.test(toString$4(node)) + ) { + file.message('All automatic links must start with a protocol', node); + } + }); + } +); +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$5(middleware, callback) { + /** @type {boolean} */ + let called; + return wrapped + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + if (fnExpectsCallback) { + parameters.push(done); + } -var remarkLintBlockquoteIndentation = unifiedLintRule( - 'remark-lint:blockquote-indentation', - blockquoteIndentation -); - -function blockquoteIndentation(tree, file, option) { - var preferred = typeof option === 'number' && !isNaN(option) ? option : null; - - unistUtilVisit(tree, 'blockquote', visitor); + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - function visitor(node) { - var abs; - var diff; - var reason; + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } - if (unistUtilGenerated(node) || node.children.length === 0) { - return + return done(exception) } - if (preferred) { - diff = preferred - check$3(node); - - if (diff !== 0) { - abs = Math.abs(diff); - reason = - (diff > 0 ? 'Add' : 'Remove') + - ' ' + - abs + - ' ' + - pluralize('space', abs) + - ' between block quote and content'; - - file.message(reason, unistUtilPosition.start(node.children[0])); + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); } - } else { - preferred = check$3(node); } } -} -function check$3(node) { - var head = node.children[0]; - var indentation = unistUtilPosition.start(head).column - unistUtilPosition.start(node).column; - var padding = mdastUtilToString$4(head).match(/^ +/); - - if (padding) { - indentation += padding[0].length; + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } } - return indentation + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-character-style - * @fileoverview - * Warn when list item checkboxes violate a given style. - * - * Options: `Object` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used checked and unchecked checkbox - * styles and warns when subsequent checkboxes use different styles. - * - * Styles can also be passed in like so: - * - * ```js - * {checked: 'x', unchecked: ' '} - * ``` - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats checked checkboxes using `x` (lowercase X) and unchecked checkboxes - * as `·` (a single space). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md", "setting": {"checked": "x"}, "gfm": true} - * - * - [x] List item - * - [x] List item - * - * @example {"name": "ok.md", "setting": {"checked": "X"}, "gfm": true} - * - * - [X] List item - * - [X] List item - * - * @example {"name": "ok.md", "setting": {"unchecked": " "}, "gfm": true} - * - * - [ ] List item - * - [ ] List item - * - [ ]·· - * - [ ] - * - * @example {"name": "ok.md", "setting": {"unchecked": "\t"}, "gfm": true} - * - * - [»] List item - * - [»] List item - * - * @example {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [x] List item - * - [X] List item - * - [ ] List item - * - [»] List item - * - * @example {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 2:5: Checked checkboxes should use `x` as a marker - * 4:5: Unchecked checkboxes should use ` ` as a marker - * - * @example {"setting": {"unchecked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} - * - * 1:1: Incorrect unchecked checkbox marker `💩`: use either `'\t'`, or `' '` + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * @example {"setting": {"checked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple * - * 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'` + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ +const primitives$4 = new Set(['string', 'number', 'boolean']); +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$4(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + Object.defineProperty(plugin, 'name', {value: id}); + return plugin + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$4(ruleId, raw); -var remarkLintCheckboxCharacterStyle = unifiedLintRule( - 'remark-lint:checkbox-character-style', - checkboxCharacterStyle -); + if (!severity) return -var start$7 = unistUtilPosition.start; -var end$4 = unistUtilPosition.end; + const fatal = severity === 2; -var checked = {x: true, X: true}; -var unchecked = {' ': true, '\t': true}; -var types$1 = {true: 'checked', false: 'unchecked'}; + return (tree, file, next) => { + let index = file.messages.length - 1; -function checkboxCharacterStyle(tree, file, option) { - var contents = String(file); - var preferred = typeof option === 'object' ? option : {}; + wrap$5(rule, (error) => { + const messages = file.messages; - if (preferred.unchecked && unchecked[preferred.unchecked] !== true) { - file.fail( - 'Incorrect unchecked checkbox marker `' + - preferred.unchecked + - "`: use either `'\\t'`, or `' '`" - ); - } + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - if (preferred.checked && checked[preferred.checked] !== true) { - file.fail( - 'Incorrect checked checkbox marker `' + - preferred.checked + - "`: use either `'x'`, or `'X'`" - ); + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); + } } +} - unistUtilVisit(tree, 'listItem', visitor); +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$4(name, value) { + /** @type {unknown[]} */ + let result; - function visitor(node) { - var type; - var point; - var value; - var style; - var reason; + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$4.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; - type = types$1[node.checked]; + // @ts-expect-error: it’s now a valid tuple. + return result +} - /* istanbul ignore next - a list item cannot be checked and empty, according - * to GFM, but theoretically it makes sense to get the end if that were - * possible. */ - point = node.children.length === 0 ? end$4(node) : start$7(node.children[0]); - // Move back to before `] `. - point.offset -= 2; - point.column -= 2; +/** + * @typedef {import('unist').Point} Point + * @typedef {import('vfile').VFile} VFile + * + * @typedef {Pick} PositionalPoint + * @typedef {Required} FullPoint + * @typedef {NonNullable} Offset + */ - // Assume we start with a checkbox, because well, `checked` is set. - value = /\[([\t Xx])]/.exec( - contents.slice(point.offset - 2, point.offset + 1) - ); +/** + * Get transform functions for the given `document`. + * + * @param {string|Uint8Array|VFile} file + */ +function location$1(file) { + var value = String(file); + /** @type {Array.} */ + var indices = []; + var search = /\r?\n|\r/g; + + while (search.test(value)) { + indices.push(search.lastIndex); + } - /* istanbul ignore if - failsafe to make sure we don‘t crash if there - * actually isn’t a checkbox. */ - if (!value) return + indices.push(value.length + 1); - style = preferred[type]; + return {toPoint, toOffset} - if (style) { - if (value[1] !== style) { - reason = - type.charAt(0).toUpperCase() + - type.slice(1) + - ' checkboxes should use `' + - style + - '` as a marker'; + /** + * Get the line and column-based `point` for `offset` in the bound indices. + * Returns a point with `undefined` values when given invalid or out of bounds + * input. + * + * @param {Offset} offset + * @returns {FullPoint} + */ + function toPoint(offset) { + var index = -1; - file.message(reason, point); + if (offset > -1 && offset < indices[indices.length - 1]) { + while (++index < indices.length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset + } + } } - } else { - preferred[type] = value[1]; } + + return {line: undefined, column: undefined, offset: undefined} + } + + /** + * Get the `offset` for a line and column-based `point` in the bound indices. + * Returns `-1` when given invalid or out of bounds input. + * + * @param {PositionalPoint} point + * @returns {Offset} + */ + function toOffset(point) { + var line = point && point.line; + var column = point && point.column; + /** @type {number} */ + var offset; + + if ( + typeof line === 'number' && + typeof column === 'number' && + !Number.isNaN(line) && + !Number.isNaN(column) && + line - 1 in indices + ) { + offset = (indices[line - 2] || 0) + column - 1 || 0; + } + + return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-content-indent - * @fileoverview - * Warn when list item checkboxes are followed by too much whitespace. - * - * @example {"name": "ok.md", "gfm": true} - * - * - [ ] List item - * + [x] List Item - * * [X] List item - * - [ ] List item - * - * @example {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [ ] List item - * + [x] List item - * * [X] List item - * - [ ] List item + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent * - * @example {"name": "not-ok.md", "label": "output", "gfm": true} + * @typedef {string} Type + * @typedef {Object} Props * - * 2:7-2:8: Checkboxes should be followed by a single character - * 3:7-3:9: Checkboxes should be followed by a single character - * 4:7-4:10: Checkboxes should be followed by a single character + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test */ +const convert$7 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$5 + } + if (typeof test === 'string') { + return typeFactory$4(test) + } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$4(test) : propsFactory$4(test) + } + if (typeof test === 'function') { + return castFactory$4(test) + } + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$4(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + while (++index < tests.length) { + checks[index] = convert$7(tests[index]); + } -var remarkLintCheckboxContentIndent = unifiedLintRule( - 'remark-lint:checkbox-content-indent', - checkboxContentIndent -); + return castFactory$4(any) -var start$8 = unistUtilPosition.start; -var end$5 = unistUtilPosition.end; + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; -var reason$9 = 'Checkboxes should be followed by a single character'; + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } -function checkboxContentIndent(tree, file) { - var contents = String(file); - var location = vfileLocation(file); + return false + } +} - unistUtilVisit(tree, 'listItem', visitor); +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$4(check) { + return castFactory$4(all) - function visitor(node) { - var initial; - var final; - var value; - var point; + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false } - /* istanbul ignore next - a list item cannot be checked and empty, according - * to GFM, but theoretically it makes sense to get the end if that were - * possible. */ - point = node.children.length === 0 ? end$5(node) : start$8(node.children[0]); - - // Assume we start with a checkbox, because well, `checked` is set. - value = /\[([\t xX])]/.exec( - contents.slice(point.offset - 4, point.offset + 1) - ); + return true + } +} - /* istanbul ignore if - failsafe to make sure we don‘t crash if there - * actually isn’t a checkbox. */ - if (!value) return +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$4(check) { + return castFactory$4(type) - // Move past checkbox. - initial = point.offset; - final = initial; + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} - while (/[\t ]/.test(contents.charAt(final))) final++; +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$4(check) { + return assertion - if (final - initial > 0) { - file.message(reason$9, { - start: location.toPosition(initial), - end: location.toPosition(final) - }); - } + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) } } +// Utility to return true. +function ok$5() { + return true +} + /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module code-block-style - * @fileoverview - * Warn when code blocks do not adhere to a given style. - * - * Options: `'consistent'`, `'fenced'`, or `'indented'`, default: `'consistent'`. - * - * `'consistent'` detects the first used code block style and warns when - * subsequent code blocks uses different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats code blocks using a fence if they have a language flag and - * indentation if not. - * Pass - * [`fences: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfences) - * to always use fences for code blocks. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"setting": "indented", "name": "ok.md"} - * - * alpha(); - * - * Paragraph. - * - * bravo(); - * - * @example {"setting": "indented", "name": "not-ok.md", "label": "input"} - * - * ``` - * alpha(); - * ``` - * - * Paragraph. - * - * ``` - * bravo(); - * ``` - * - * @example {"setting": "indented", "name": "not-ok.md", "label": "output"} - * - * 1:1-3:4: Code blocks should be indented - * 7:1-9:4: Code blocks should be indented - * - * @example {"setting": "fenced", "name": "ok.md"} - * - * ``` - * alpha(); - * ``` - * - * Paragraph. - * - * ``` - * bravo(); - * ``` - * - * @example {"setting": "fenced", "name": "not-ok-fenced.md", "label": "input"} - * - * alpha(); - * - * Paragraph. - * - * bravo(); - * - * @example {"setting": "fenced", "name": "not-ok-fenced.md", "label": "output"} - * - * 1:1-1:13: Code blocks should be fenced - * 5:1-5:13: Code blocks should be fenced - * - * @example {"name": "not-ok-consistent.md", "label": "input"} - * - * alpha(); - * - * Paragraph. - * - * ``` - * bravo(); - * ``` - * - * @example {"name": "not-ok-consistent.md", "label": "output"} - * - * 5:1-7:4: Code blocks should be indented - * - * @example {"setting": "💩", "name": "not-ok-incorrect.md", "label": "output", "config": {"positionless": true}} - * - * 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'` + * @param {string} d + * @returns {string} */ +function color$5(d) { + return '\u001B[33m' + d + '\u001B[39m' +} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ +/** + * Continue traversing as normal + */ +const CONTINUE$4 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$4 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$4 = false; +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$4 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + const is = convert$7(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$5(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + return visit -var remarkLintCodeBlockStyle = unifiedLintRule('remark-lint:code-block-style', codeBlockStyle); + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; -var start$9 = unistUtilPosition.start; -var end$6 = unistUtilPosition.end; + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$4(visitor(node, parents)); -var styles$3 = {null: true, fenced: true, indented: true}; + if (result[0] === EXIT$4) { + return result + } + } -function codeBlockStyle(tree, file, option) { - var contents = String(file); - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$4) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); - if (styles$3[preferred] !== true) { - file.fail( - 'Incorrect code block style `' + - preferred + - "`: use either `'consistent'`, `'fenced'`, or `'indented'`" - ); - } + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); - unistUtilVisit(tree, 'code', visitor); + if (subresult[0] === EXIT$4) { + return subresult + } - function visitor(node) { - var initial; - var final; - var current; + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } - if (unistUtilGenerated(node)) { - return null + return result + } + } } + ); - initial = start$9(node).offset; - final = end$6(node).offset; - - current = - node.lang || /^\s*([~`])\1{2,}/.test(contents.slice(initial, final)) - ? 'fenced' - : 'indented'; +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$4(value) { + if (Array.isArray(value)) { + return value + } - if (preferred) { - if (preferred !== current) { - file.message('Code blocks should be ' + preferred, node); - } - } else { - preferred = current; - } + if (typeof value === 'number') { + return [CONTINUE$4, value] } + + return [value] } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module definition-spacing - * @fileoverview - * Warn when consecutive whitespace is used in a definition. - * - * @example {"name": "ok.md"} - * - * [example domain]: http://example.com "Example Domain" + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test * - * @example {"name": "not-ok.md", "label": "input"} + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$4 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$4(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point * - * [example····domain]: http://example.com "Example Domain" + * @typedef {Partial} PointLike * - * @example {"name": "not-ok.md", "label": "output"} + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] * - * 1:1-1:57: Do not use consecutive whitespace in definition labels + * @typedef {Object} NodeLike + * @property {PositionLike} [position] */ +var pointStart$2 = point$3('start'); +var pointEnd$1 = point$3('end'); +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$3(type) { + return point + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; - - -var remarkLintDefinitionSpacing = unifiedLintRule('remark-lint:definition-spacing', definitionSpacing); - -var label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; -var reason$a = 'Do not use consecutive whitespace in definition labels'; - -function definitionSpacing(tree, file) { - var contents = String(file); - - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], check); - - function check(node) { - var start = unistUtilPosition.start(node).offset; - var end = unistUtilPosition.end(node).offset; - - if ( - !unistUtilGenerated(node) && - /[ \t\n]{2,}/.test(contents.slice(start, end).match(label)[1]) - ) { - file.message(reason$a, node); + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null } } } @@ -43598,1231 +44389,1431 @@ function definitionSpacing(tree, file) { * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT - * @module fenced-code-flag + * @module no-blockquote-without-marker * @fileoverview - * Check fenced code block flags. - * - * Options: `Array.` or `Object`, optional. - * - * Providing an array is as passing `{flags: Array}`. - * - * The object can have an array of `'flags'` which are allowed: other flags - * will not be allowed. - * An `allowEmpty` field (`boolean`, default: `false`) can be set to allow - * code blocks without language flags. - * - * @example {"name": "ok.md"} - * - * ```alpha - * bravo(); - * ``` - * - * @example {"name": "not-ok.md", "label": "input"} + * Warn when blank lines without `>` (greater than) markers are found in a + * block quote. * - * ``` - * alpha(); - * ``` + * ## Fix * - * @example {"name": "not-ok.md", "label": "output"} + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds markers to every line in a block quote. * - * 1:1-3:4: Missing code language flag + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. * - * @example {"name": "ok.md", "setting": {"allowEmpty": true}} + * @example + * {"name": "ok.md"} * - * ``` - * alpha(); - * ``` + * > Foo… + * > …bar… + * > …baz. * - * @example {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "input"} + * @example + * {"name": "ok-tabs.md"} * - * ``` - * alpha(); - * ``` + * >»Foo… + * >»…bar… + * >»…baz. * - * @example {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "output"} + * @example + * {"name": "not-ok.md", "label": "input"} * - * 1:1-3:4: Missing code language flag + * > Foo… + * …bar… + * > …baz. * - * @example {"name": "ok.md", "setting": ["alpha"]} + * @example + * {"name": "not-ok.md", "label": "output"} * - * ```alpha - * bravo(); - * ``` + * 2:1: Missing marker in block quote * - * @example {"name": "not-ok.md", "setting": ["charlie"], "label": "input"} + * @example + * {"name": "not-ok-tabs.md", "label": "input"} * - * ```alpha - * bravo(); - * ``` + * >»Foo… + * »…bar… + * …baz. * - * @example {"name": "not-ok.md", "setting": ["charlie"], "label": "output"} + * @example + * {"name": "not-ok-tabs.md", "label": "output"} * - * 1:1-3:4: Incorrect code language flag + * 2:1: Missing marker in block quote + * 3:1: Missing marker in block quote */ +const remarkLintNoBlockquoteWithoutMarker = lintRule$4( + 'remark-lint:no-blockquote-without-marker', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + const loc = location$1(file); + visit$4(tree, 'blockquote', (node) => { + let index = -1; + while (++index < node.children.length) { + const child = node.children[index]; + if (child.type === 'paragraph' && !generated(child)) { + const end = pointEnd$1(child).line; + const column = pointStart$2(child).column; + let line = pointStart$2(child).line; + // Skip past the first line. + while (++line <= end) { + const offset = loc.toOffset({line, column}); -var remarkLintFencedCodeFlag = unifiedLintRule('remark-lint:fenced-code-flag', fencedCodeFlag); + if (/>[\t ]+$/.test(value.slice(offset - 5, offset))) { + continue + } -var start$a = unistUtilPosition.start; -var end$7 = unistUtilPosition.end; + // Roughly here. + file.message('Missing marker in block quote', { + line, + column: column - 2 + }); + } + } + } + }); + } +); -var fence = /^ {0,3}([~`])\1{2,}/; -var reasonIncorrect = 'Incorrect code language flag'; -var reasonMissing = 'Missing code language flag'; +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ -function fencedCodeFlag(tree, file, option) { - var contents = String(file); - var allowEmpty = false; - var allowed = []; - var flags = option; +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$6(middleware, callback) { + /** @type {boolean} */ + let called; - if (typeof flags === 'object' && !('length' in flags)) { - allowEmpty = Boolean(flags.allowEmpty); - flags = flags.flags; - } + return wrapped - if (typeof flags === 'object' && 'length' in flags) { - allowed = String(flags).split(','); - } + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; - unistUtilVisit(tree, 'code', visitor); + if (fnExpectsCallback) { + parameters.push(done); + } - function visitor(node) { - var value; + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - if (!unistUtilGenerated(node)) { - if (node.lang) { - if (allowed.length !== 0 && allowed.indexOf(node.lang) === -1) { - file.message(reasonIncorrect, node); - } - } else { - value = contents.slice(start$a(node).offset, end$7(node).offset); + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } - if (!allowEmpty && fence.test(value)) { - file.message(reasonMissing, node); - } + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); } } } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module fenced-code-marker - * @fileoverview - * Warn for violating fenced code markers. - * - * Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`. + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * `'consistent'` detects the first used fenced code marker style and warns - * when subsequent fenced code blocks use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats fences using ``'`'`` (grave accent) by default. - * Pass - * [`fence: '~'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfence) - * to use `~` (tilde) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md"} - * - * Indented code blocks are not affected by this rule: - * - * bravo(); - * - * @example {"name": "ok.md", "setting": "`"} - * - * ```alpha - * bravo(); - * ``` - * - * ``` - * charlie(); - * ``` - * - * @example {"name": "ok.md", "setting": "~"} - * - * ~~~alpha - * bravo(); - * ~~~ - * - * ~~~ - * charlie(); - * ~~~ - * - * @example {"name": "not-ok-consistent-tick.md", "label": "input"} + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple * - * ```alpha - * bravo(); - * ``` - * - * ~~~ - * charlie(); - * ~~~ - * - * @example {"name": "not-ok-consistent-tick.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `` ` `` as a marker - * - * @example {"name": "not-ok-consistent-tilde.md", "label": "input"} - * - * ~~~alpha - * bravo(); - * ~~~ - * - * ``` - * charlie(); - * ``` - * - * @example {"name": "not-ok-consistent-tilde.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `~` as a marker - * - * @example {"name": "not-ok-incorrect.md", "setting": "💩", "label": "output", "config": {"positionless": true}} - * - * 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'` + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ +const primitives$5 = new Set(['string', 'number', 'boolean']); +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$5(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + Object.defineProperty(plugin, 'name', {value: id}); + return plugin + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$5(ruleId, raw); -var remarkLintFencedCodeMarker = unifiedLintRule('remark-lint:fenced-code-marker', fencedCodeMarker); - -var markers = { - '`': true, - '~': true, - null: true -}; - -function fencedCodeMarker(tree, file, option) { - var contents = String(file); - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; + if (!severity) return - if (markers[preferred] !== true) { - file.fail( - 'Incorrect fenced code marker `' + - preferred + - "`: use either `'consistent'`, `` '`' ``, or `'~'`" - ); - } + const fatal = severity === 2; - unistUtilVisit(tree, 'code', visitor); + return (tree, file, next) => { + let index = file.messages.length - 1; - function visitor(node) { - var start; - var marker; - var label; + wrap$6(rule, (error) => { + const messages = file.messages; - if (!unistUtilGenerated(node)) { - start = unistUtilPosition.start(node).offset; - marker = contents - .slice(start, start + 4) - .replace(/^\s+/, '') - .charAt(0); + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - // Ignore unfenced code blocks. - if (markers[marker] === true) { - if (preferred) { - if (marker !== preferred) { - label = preferred === '~' ? preferred : '` ` `'; - file.message( - 'Fenced code should use `' + label + '` as a marker', - node - ); - } - } else { - preferred = marker; + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); } - } + + next(); + })(tree, file, options); } } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module file-extension - * @fileoverview - * Warn when the file extension differ from the preferred extension. - * - * Does not warn when given documents have no file extensions (such as - * `AUTHORS` or `LICENSE`). - * - * Options: `string`, default: `'md'` — Expected file extension. - * - * @example {"name": "readme.md"} - * - * @example {"name": "readme"} - * - * @example {"name": "readme.mkd", "label": "output", "config": {"positionless": true}} - * - * 1:1: Incorrect extension: use `md` + * Coerce a value to a severity--options tuple. * - * @example {"name": "readme.mkd", "setting": "mkd"} + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} */ +function coerce$5(name, value) { + /** @type {unknown[]} */ + let result; + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$5.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + let level = result[0]; -var remarkLintFileExtension = unifiedLintRule('remark-lint:file-extension', fileExtension); - -function fileExtension(tree, file, option) { - var ext = file.extname; - var preferred = typeof option === 'string' ? option : 'md'; + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } - if (ext && ext.slice(1) !== preferred) { - file.message('Incorrect extension: use `' + preferred + '`'); + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-definition - * @fileoverview - * Warn when definitions are placed somewhere other than at the end of - * the file. - * - * @example {"name": "ok.md"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * @example {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * Another paragraph. - * - * @example {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:47: Move definitions to the end of the file (after the node at line `5`) - * - * @example {"name": "ok-comments.md"} - * - * Paragraph. + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent * - * [example-1]: http://example.com/one/ - * - * + * @typedef {string} Type + * @typedef {Object} Props * - * [example-2]: http://example.com/two/ + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test */ +const convert$8 = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$6 + } + if (typeof test === 'string') { + return typeFactory$5(test) + } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$5(test) : propsFactory$5(test) + } + if (typeof test === 'function') { + return castFactory$5(test) + } + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$5(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; -var remarkLintFinalDefinition = unifiedLintRule('remark-lint:final-definition', finalDefinition); - -var start$b = unistUtilPosition.start; - -function finalDefinition(tree, file) { - var last = null; + while (++index < tests.length) { + checks[index] = convert$8(tests[index]); + } - unistUtilVisit(tree, visitor, true); + return castFactory$5(any) - function visitor(node) { - var line = start$b(node).line; + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; - // Ignore generated and HTML comment nodes. - if (node.type === 'root' || unistUtilGenerated(node) || (node.type === 'html' && /^\s* + * + * [example-2]: http://example.com/two/ + */ + +const remarkLintFinalDefinition = lintRule$n( + 'remark-lint:final-definition', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + let last = 0; + + visit$m( + tree, + (node) => { + // Ignore generated and HTML comment nodes. + if ( + node.type === 'root' || + generated(node) || + (node.type === 'html' && /^\s*".length)); + + validateMeta(node, file, meta); + } catch (e) { + file.message(e, node); + } + }); +} + +const remarkLintNodejsYamlComments = lintRule$A( + "remark-lint:nodejs-yaml-comments", + validateYAMLComments +); + +var escapeStringRegexp$1 = string => { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } + + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a \unnnn escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +}; + +var start$1 = factory$3('start'); +var end = factory$3('end'); + +var unistUtilPosition = position$3; + +position$3.start = start$1; +position$3.end = end; + +function position$3(node) { + return {start: start$1(node), end: end(node)} +} + +function factory$3(type) { + point.displayName = type; + + return point + + function point(node) { + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: isNaN(point.offset) ? null : point.offset + } + } +} + +var convert_1 = convert$z; + +function convert$z(test) { + if (test == null) { + return ok$x + } + + if (typeof test === 'string') { + return typeFactory$w(test) + } + + if (typeof test === 'object') { + return 'length' in test ? anyFactory$w(test) : allFactory(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function allFactory(test) { + return all + + function all(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) return false + } + + return true + } +} + +function anyFactory$w(tests) { + var checks = []; + var index = -1; + + while (++index < tests.length) { + checks[index] = convert$z(tests[index]); + } + + return any + + function any() { + var index = -1; + + while (++index < checks.length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$w(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$x() { + return true +} + +var color_1 = color$x; +function color$x(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +var unistUtilVisitParents = visitParents$w; + + + + +var CONTINUE$w = true; +var SKIP$w = 'skip'; +var EXIT$w = false; + +visitParents$w.CONTINUE = CONTINUE$w; +visitParents$w.SKIP = SKIP$w; +visitParents$w.EXIT = EXIT$w; + +function visitParents$w(tree, test, visitor, reverse) { + var step; + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1(test); + step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + function factory(node, index, parents) { + var value = typeof node === 'object' && node !== null ? node : {}; + var name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + visit.displayName = + 'node (' + color_1(value.type + (name ? '<' + name + '>' : '')) + ')'; + } + + return visit + + function visit() { + var grandparents = parents.concat(node); + var result = []; + var subresult; + var offset; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$w(visitor(node, parents)); + + if (result[0] === EXIT$w) { + return result + } + } + + if (node.children && result[0] !== SKIP$w) { + offset = (reverse ? node.children.length : -1) + step; + + while (offset > -1 && offset < node.children.length) { + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$w) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } +} + +function toResult$w(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$w, value] + } + + return [value] +} + +var unistUtilVisit = visit$w; + + + +var CONTINUE$x = unistUtilVisitParents.CONTINUE; +var SKIP$x = unistUtilVisitParents.SKIP; +var EXIT$x = unistUtilVisitParents.EXIT; + +visit$w.CONTINUE = CONTINUE$x; +visit$w.SKIP = SKIP$x; +visit$w.EXIT = EXIT$x; + +function visit$w(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var vfileLocation = factory$4; + +function factory$4(file) { + var value = String(file); + var indices = []; + var search = /\r?\n|\r/g; + + while (search.exec(value)) { + indices.push(search.lastIndex); + } + + indices.push(value.length + 1); + + return { + toPoint: offsetToPoint, + toPosition: offsetToPoint, + toOffset: pointToOffset + } + + // Get the line and column-based `point` for `offset` in the bound indices. + function offsetToPoint(offset) { + var index = -1; + + if (offset > -1 && offset < indices[indices.length - 1]) { + while (++index < indices.length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + } + + return {} + } + + // Get the `offset` for a line and column-based `point` in the bound + // indices. + function pointToOffset(point) { + var line = point && point.line; + var column = point && point.column; + var offset; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + offset = (indices[line - 2] || 0) + column - 1 || 0; + } + + return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 + } +} + +const start$2 = unistUtilPosition.start; + +var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); + +function testProhibited (val, content) { + let regexpFlags = 'g'; + let no = val.no; + + if (!no) { + no = escapeStringRegexp$1(val.yes); + regexpFlags += 'i'; + } + + let regexpString = '(? { + const results = testProhibited(val, content); + if (results.length) { + results.forEach(({ result, index }) => { + const message = val.yes ? `Use "${val.yes}" instead of "${result}"` : `Do not use "${result}"`; + file.message(message, { + start: location.toPoint(initial + index), + end: location.toPoint(initial + index + [...result].length) + }); + }); + } + }); + } +} + +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$C(middleware, callback) { + /** @type {boolean} */ + let called; + + return wrapped + + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + + if (fnExpectsCallback) { + parameters.push(done); + } + + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; + + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } + + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ + +const primitives$B = new Set(['string', 'number', 'boolean']); + +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$B(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + + Object.defineProperty(plugin, 'name', {value: id}); + + return plugin + + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$C(ruleId, raw); + + if (!severity) return + + const fatal = severity === 2; + + return (tree, file, next) => { + let index = file.messages.length - 1; + + wrap$C(rule, (error) => { + const messages = file.messages; + + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } + + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); + } + } +} + +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$C(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$B.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ + +const convert$A = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$y + } + + if (typeof test === 'string') { + return typeFactory$x(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$x(test) : propsFactory$w(test) + } + + if (typeof test === 'function') { + return castFactory$w(test) + } + + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$x(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + + while (++index < tests.length) { + checks[index] = convert$A(tests[index]); + } + + return castFactory$w(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } + + return false + } +} + +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$w(check) { + return castFactory$w(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$x(check) { + return castFactory$w(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$w(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} + +// Utility to return true. +function ok$y() { + return true +} + +/** + * @param {string} d + * @returns {string} + */ +function color$y(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ + +/** + * Continue traversing as normal + */ +const CONTINUE$y = true; +/** + * Do not traverse this node’s children + */ +const SKIP$y = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$y = false; + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$x = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + const is = convert$A(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$y(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$x(visitor(node, parents)); + + if (result[0] === EXIT$y) { + return result + } + } + + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$y) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); + + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$y) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$x(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$y, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$x = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$x(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart$m = point$p('start'); +var pointEnd$c = point$p('end'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$p(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } + } +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module rule-style + * @fileoverview + * Warn when the thematic breaks (horizontal rules) violate a given or + * detected style. + * + * Options: `string`, either a corect thematic breaks such as `***`, or + * `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used thematic break style and warns when + * subsequent rules use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * has three settings that define how rules are created: + * + * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) + * (default: `*`) — Marker to use + * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) + * (default: `3`) — Number of markers to use + * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) + * (default: `true`) — Whether to pad markers with spaces + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "* * *"} + * + * * * * + * + * * * * + * + * @example + * {"name": "ok.md", "setting": "_______"} + * + * _______ + * + * _______ + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * *** + * + * * * * + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:6: Rules should use `***` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` + */ + +const remarkLintRuleStyle = lintRule$B( + 'remark-lint:rule-style', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && /[^-_* ]/.test(option)) { + file.fail( + "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" + ); + } + + visit$x(tree, 'thematicBreak', (node) => { + const initial = pointStart$m(node).offset; + const final = pointEnd$c(node).offset; + + if (typeof initial === 'number' && typeof final === 'number') { + const rule = value.slice(initial, final); + + if (option === 'consistent') { + option = rule; + } else if (rule !== option) { + file.message('Rules should use `' + option + '`', node); + } + } + }); + } +); + +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$D(middleware, callback) { + /** @type {boolean} */ + let called; + + return wrapped + + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + + if (fnExpectsCallback) { + parameters.push(done); + } + + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; + + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } + + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ + +const primitives$C = new Set(['string', 'number', 'boolean']); + +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$C(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + + Object.defineProperty(plugin, 'name', {value: id}); + + return plugin + + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$D(ruleId, raw); + + if (!severity) return + + const fatal = severity === 2; + + return (tree, file, next) => { + let index = file.messages.length - 1; + + wrap$D(rule, (error) => { + const messages = file.messages; + + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } + + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); + } + } +} + +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$D(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$C.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ + +const convert$B = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$z + } + + if (typeof test === 'string') { + return typeFactory$y(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$y(test) : propsFactory$x(test) + } + + if (typeof test === 'function') { + return castFactory$x(test) + } + + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$y(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + + while (++index < tests.length) { + checks[index] = convert$B(tests[index]); + } + + return castFactory$x(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } + + return false + } +} + +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$x(check) { + return castFactory$x(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$y(check) { + return castFactory$x(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$x(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} + +// Utility to return true. +function ok$z() { + return true +} + +/** + * @param {string} d + * @returns {string} + */ +function color$z(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ + +/** + * Continue traversing as normal + */ +const CONTINUE$z = true; +/** + * Do not traverse this node’s children + */ +const SKIP$z = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$z = false; + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$y = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + const is = convert$B(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$z(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$y(visitor(node, parents)); + + if (result[0] === EXIT$z) { + return result + } + } + + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$z) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); + + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$z) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$y(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$z, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$y = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$y(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart$n = point$q('start'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$q(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } + } +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module strong-marker + * @fileoverview + * Warn for violating importance (strong) markers. + * + * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. + * + * `'consistent'` detects the first used importance style and warns when + * subsequent importance sequences use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats importance using an `*` (asterisk) by default. + * Pass + * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) + * to use `_` (underscore) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * **foo** and **bar**. + * + * @example + * {"name": "also-ok.md"} + * + * __foo__ and __bar__. + * + * @example + * {"name": "ok.md", "setting": "*"} + * + * **foo**. + * + * @example + * {"name": "ok.md", "setting": "_"} + * + * __foo__. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * **foo** and __bar__. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:13-1:20: Strong should use `*` as a marker + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` + */ + +const remarkLintStrongMarker = lintRule$C( + 'remark-lint:strong-marker', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== '*' && option !== '_' && option !== 'consistent') { + file.fail( + 'Incorrect strong marker `' + + option + + "`: use either `'consistent'`, `'*'`, or `'_'`" + ); + } + + visit$y(tree, 'strong', (node) => { + const start = pointStart$n(node).offset; + + if (typeof start === 'number') { + const marker = /** @type {Marker} */ (value.charAt(start)); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Strong should use `' + option + '` as a marker', node); + } + } + }); + } +); + +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$E(middleware, callback) { + /** @type {boolean} */ + let called; + + return wrapped + + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + + if (fnExpectsCallback) { + parameters.push(done); + } + + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; + + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } + + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ + +const primitives$D = new Set(['string', 'number', 'boolean']); + +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$D(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + + Object.defineProperty(plugin, 'name', {value: id}); + + return plugin + + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$E(ruleId, raw); + + if (!severity) return + + const fatal = severity === 2; + + return (tree, file, next) => { + let index = file.messages.length - 1; + + wrap$E(rule, (error) => { + const messages = file.messages; + + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } + + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); + } + } +} + +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$E(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$D.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ + +const convert$C = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$A } - other = new SemVer(other, this.options); - } - if (other.version === this.version) { - return 0 + if (typeof test === 'string') { + return typeFactory$z(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$z(test) : propsFactory$y(test) + } + + if (typeof test === 'function') { + return castFactory$y(test) + } + + throw new Error('Expected function, string, or object as test') } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$z(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; - return this.compareMain(other) || this.comparePre(other) + while (++index < tests.length) { + checks[index] = convert$C(tests[index]); } - compareMain (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + return castFactory$y(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true } - return ( - compareIdentifiers$1(this.major, other.major) || - compareIdentifiers$1(this.minor, other.minor) || - compareIdentifiers$1(this.patch, other.patch) - ) + return false } +} - comparePre (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); - } +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$y(check) { + return castFactory$y(all) - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false } - let i = 0; - do { - const a = this.prerelease[i]; - const b = other.prerelease[i]; - debug_1('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers$1(a, b) - } - } while (++i) + return true } +} - compareBuild (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); - } +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$z(check) { + return castFactory$y(type) - let i = 0; - do { - const a = this.build[i]; - const b = other.build[i]; - debug_1('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers$1(a, b) - } - } while (++i) + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check } +} - // preminor will bump the version up to the next minor release, and immediately - // down to pre-release. premajor and prepatch work the same way. - inc (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc('pre', identifier); - break - case 'preminor': - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc('pre', identifier); - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0; - this.inc('patch', identifier); - this.inc('pre', identifier); - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier); - } - this.inc('pre', identifier); - break +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$y(check) { + return assertion - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if ( - this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0 - ) { - this.major++; - } - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++; - } - this.patch = 0; - this.prerelease = []; - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++; + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} + +// Utility to return true. +function ok$A() { + return true +} + +/** + * @param {string} d + * @returns {string} + */ +function color$A(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ + +/** + * Continue traversing as normal + */ +const CONTINUE$A = true; +/** + * Do not traverse this node’s children + */ +const SKIP$A = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$A = false; + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$z = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + const is = convert$C(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$A(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); } - this.prerelease = []; - break - // This probably shouldn't be used publicly. - // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0]; - } else { - let i = this.prerelease.length; - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++; - i = -2; + + return visit + + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$z(visitor(node, parents)); + + if (result[0] === EXIT$A) { + return result } } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0); + + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$A) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); + + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$A) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } } + + return result } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0]; + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$z(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$A, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$z = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$z(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart$o = point$r('start'); +var pointEnd$d = point$r('end'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$r(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } + } +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module table-cell-padding + * @fileoverview + * Warn when table cells are incorrectly padded. + * + * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. + * + * `'consistent'` detects the first used cell padding style and warns when + * subsequent cells use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats tables with padding by default. + * Pass + * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) + * to not use padding. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "padded", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} + * + * | A | B | + * | :----|----: | + * | Alpha|Bravo | + * + * | C | D | + * | :----- | ---: | + * |Charlie | Delta| + * + * Too much padding isn’t good either: + * + * | E | F | G | H | + * | :---- | -------- | :----: | -----: | + * | Echo | Foxtrot | Golf | Hotel | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:8: Cell should be padded + * 3:9: Cell should be padded + * 7:2: Cell should be padded + * 7:17: Cell should be padded + * 13:9: Cell should be padded with 1 space, not 2 + * 13:20: Cell should be padded with 1 space, not 2 + * 13:21: Cell should be padded with 1 space, not 2 + * 13:29: Cell should be padded with 1 space, not 2 + * 13:30: Cell should be padded with 1 space, not 2 + * + * @example + * {"name": "ok.md", "setting": "compact", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} + * + * | A | B | + * | -----| -----| + * | Alpha| Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} + * + * 3:2: Cell should be compact + * 3:11: Cell should be compact + * 7:16: Cell should be compact + * + * @example + * {"name": "ok-padded.md", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | ------- | ----- | + * | Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | :----- | ----: | + * |Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:2: Cell should be padded + * + * @example + * {"name": "ok-compact.md", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C |D | + * |-------|-----| + * |Charlie|Delta| + * + * @example + * {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:16: Cell should be compact + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} + * + * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` + * + * @example + * {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} + * + * + * + * | | Alpha | Bravo| + * | ------ | ----- | ---: | + * | Charlie| | Echo| + * + * @example + * {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:25: Cell should be padded + * 5:10: Cell should be padded + * 5:25: Cell should be padded + * + * @example + * {"name": "missing-body.md", "setting": "padded", "gfm": true} + * + * + * + * | Alpha | Bravo | Charlie | + * | ----- | ------- | ------- | + * | Delta | + * | Echo | Foxtrot | + */ + +const remarkLintTableCellPadding = lintRule$D( + 'remark-lint:table-cell-padding', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + if ( + option !== 'padded' && + option !== 'compact' && + option !== 'consistent' + ) { + file.fail( + 'Incorrect table cell padding style `' + + option + + "`, expected `'padded'`, `'compact'`, or `'consistent'`" + ); + } + + visit$z(tree, 'table', (node) => { + const rows = node.children; + // To do: fix types to always have `align` defined. + /* c8 ignore next */ + const align = node.align || []; + /** @type {number[]} */ + const sizes = Array.from({length: align.length}); + /** @type {Entry[]} */ + const entries = []; + let index = -1; + + // Check rows. + while (++index < rows.length) { + const row = rows[index]; + let column = -1; + + // Check fences (before, between, and after cells). + while (++column < row.children.length) { + const cell = row.children[column]; + + if (cell.children.length > 0) { + const cellStart = pointStart$o(cell).offset; + const cellEnd = pointEnd$d(cell).offset; + const contentStart = pointStart$o(cell.children[0]).offset; + const contentEnd = pointEnd$d( + cell.children[cell.children.length - 1] + ).offset; + + if ( + typeof cellStart !== 'number' || + typeof cellEnd !== 'number' || + typeof contentStart !== 'number' || + typeof contentEnd !== 'number' + ) { + continue } - } else { - this.prerelease = [identifier, 0]; + + entries.push({ + node: cell, + start: contentStart - cellStart - (column ? 0 : 1), + end: cellEnd - contentEnd - 1, + column + }); + + // Detect max space per column. + sizes[column] = Math.max( + sizes[column] || 0, + contentEnd - contentStart + ); } } - break + } - default: - throw new Error(`invalid increment argument: ${release}`) + const style = + option === 'consistent' + ? entries[0] && (!entries[0].start || !entries[0].end) + ? 0 + : 1 + : option === 'padded' + ? 1 + : 0; + + index = -1; + + while (++index < entries.length) { + checkSide('start', entries[index], style, sizes); + checkSide('end', entries[index], style, sizes); + } + + return SKIP$A + }); + + /** + * @param {'start'|'end'} side + * @param {Entry} entry + * @param {0|1} style + * @param {number[]} sizes + */ + function checkSide(side, entry, style, sizes) { + const cell = entry.node; + const column = entry.column; + const spacing = entry[side]; + + if (spacing === undefined || spacing === style) { + return + } + + let reason = 'Cell should be '; + + if (style === 0) { + // Ignore every cell except the biggest in the column. + if (size$1(cell) < sizes[column]) { + return + } + + reason += 'compact'; + } else { + reason += 'padded'; + + if (spacing > style) { + // May be right or center aligned. + if (size$1(cell) < sizes[column]) { + return + } + + reason += ' with 1 space, not ' + spacing; + } + } + + /** @type {Point} */ + let point; + + if (side === 'start') { + point = pointStart$o(cell); + if (!column) { + point.column++; + + if (typeof point.offset === 'number') { + point.offset++; + } + } + } else { + point = pointEnd$d(cell); + point.column--; + + if (typeof point.offset === 'number') { + point.offset--; + } + } + + file.message(reason, point); } - this.format(); - this.raw = this.version; - return this } +); + +/** + * @param {TableCell} node + * @returns {number} + */ +function size$1(node) { + const head = pointStart$o(node.children[0]).offset; + const tail = pointEnd$d(node.children[node.children.length - 1]).offset; + // Only called when we’re sure offsets exist. + /* c8 ignore next */ + return typeof head === 'number' && typeof tail === 'number' ? tail - head : 0 } -var semver = SemVer; +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$F(middleware, callback) { + /** @type {boolean} */ + let called; -const {MAX_LENGTH: MAX_LENGTH$4} = constants$3; -const { re: re$3, t: t$1 } = re_1; + return wrapped + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + if (fnExpectsCallback) { + parameters.push(done); + } -const parse$9 = (version, options) => { - options = parseOptions_1(options); + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - if (version instanceof semver) { - return version - } + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } - if (typeof version !== 'string') { - return null - } + return done(exception) + } - if (version.length > MAX_LENGTH$4) { - return null + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } } - const r = options.loose ? re$3[t$1.LOOSE] : re$3[t$1.FULL]; - if (!r.test(version)) { - return null + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } } - try { - return new semver(version, options) - } catch (er) { - return null + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); } -}; +} -var parse_1$4 = parse$9; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ -const compare$2 = (a, b, loose) => - new semver(a, loose).compare(new semver(b, loose)); +const primitives$E = new Set(['string', 'number', 'boolean']); -var compare_1 = compare$2; +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$E(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; -const lt$1 = (a, b, loose) => compare_1(a, b, loose) < 0; -var lt_1 = lt$1; + Object.defineProperty(plugin, 'name', {value: id}); -const allowedKeys = [ - "added", - "napiVersion", - "deprecated", - "removed", - "changes", -]; -const changesExpectedKeys = ["version", "pr-url", "description"]; -const VERSION_PLACEHOLDER = "REPLACEME"; -const MAX_SAFE_SEMVER_VERSION = parse_1$4( - Array.from({ length: 3 }, () => Number.MAX_SAFE_INTEGER).join(".") -); -const validVersionNumberRegex = /^v\d+\.\d+\.\d+$/; -const prUrlRegex = new RegExp("^https://github.com/nodejs/node/pull/\\d+$"); -const privatePRUrl = "https://github.com/nodejs-private/node-private/pull/"; + return plugin -let releasedVersions; -let invalidVersionMessage = "version(s) must respect the pattern `vx.x.x` or"; -if (process.env.NODE_RELEASED_VERSIONS) { - console.log("Using release list from env..."); - releasedVersions = process.env.NODE_RELEASED_VERSIONS.split(",").map( - (v) => `v${v}` - ); - invalidVersionMessage = `version not listed in the changelogs, `; -} -invalidVersionMessage += `use the placeholder \`${VERSION_PLACEHOLDER}\``; + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$F(ruleId, raw); -const kContainsIllegalKey = Symbol("illegal key"); -const kWrongKeyOrder = Symbol("Wrong key order"); -function unorderedKeys(meta) { - const keys = Object.keys(meta); - let previousKeyIndex = -1; - for (const key of keys) { - const keyIndex = allowedKeys.indexOf(key); - if (keyIndex <= previousKeyIndex) { - return keyIndex === -1 ? kContainsIllegalKey : kWrongKeyOrder; - } - previousKeyIndex = keyIndex; - } -} + if (!severity) return -function containsInvalidVersionNumber(version) { - if (Array.isArray(version)) { - return version.some(containsInvalidVersionNumber); - } + const fatal = severity === 2; - if (version === undefined || version === VERSION_PLACEHOLDER) return false; + return (tree, file, next) => { + let index = file.messages.length - 1; - if ( - releasedVersions && - // Always ignore 0.0.x and 0.1.x release numbers: - (version[1] !== "0" || (version[3] !== "0" && version[3] !== "1")) - ) - return !releasedVersions.includes(version); + wrap$F(rule, (error) => { + const messages = file.messages; - return !validVersionNumberRegex.test(version); -} -const getValidSemver = (version) => - version === VERSION_PLACEHOLDER ? MAX_SAFE_SEMVER_VERSION : version; -function areVersionsUnordered(versions) { - if (!Array.isArray(versions)) return false; + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - for (let index = 1; index < versions.length; index++) { - if ( - lt_1( - getValidSemver(versions[index - 1]), - getValidSemver(versions[index]) - ) - ) { - return true; + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); + } + + next(); + })(tree, file, options); } } } -function invalidChangesKeys(change) { - const keys = Object.keys(change); - const { length } = keys; - if (length !== changesExpectedKeys.length) return true; - for (let index = 0; index < length; index++) { - if (keys[index] !== changesExpectedKeys[index]) return true; +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$F(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$E.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; } -} -function validateSecurityChange(file, node, change, index) { - if ("commit" in change) { - if (typeof change.commit !== "string" || isNaN(`0x${change.commit}`)) { - file.message( - `changes[${index}]: Ill-formed security change commit ID`, - node - ); - } - if (Object.keys(change)[1] === "commit") { - change = { ...change }; - delete change.commit; + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; } } - if (invalidChangesKeys(change)) { - const securityChangeExpectedKeys = [...changesExpectedKeys]; - securityChangeExpectedKeys[0] += "[, commit]"; - file.message( - `changes[${index}]: Invalid keys. Expected keys are: ` + - securityChangeExpectedKeys.join(", "), - node - ); + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result } -function validateChanges(file, node, changes) { - if (!Array.isArray(changes)) - return file.message("`changes` must be a YAML list", node); - const changesVersions = []; - for (let index = 0; index < changes.length; index++) { - const change = changes[index]; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ - const isAncient = - typeof change.version === "string" && change.version.startsWith("v0."); - const isSecurityChange = - !isAncient && - typeof change["pr-url"] === "string" && - change["pr-url"].startsWith(privatePRUrl); +const convert$D = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$B + } - if (isSecurityChange) { - validateSecurityChange(file, node, change, index); - } else if (!isAncient && invalidChangesKeys(change)) { - file.message( - `changes[${index}]: Invalid keys. Expected keys are: ` + - changesExpectedKeys.join(", "), - node - ); - } + if (typeof test === 'string') { + return typeFactory$A(test) + } - if (containsInvalidVersionNumber(change.version)) { - file.message(`changes[${index}]: ${invalidVersionMessage}`, node); - } else if (areVersionsUnordered(change.version)) { - file.message(`changes[${index}]: list of versions is not in order`, node); - } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$A(test) : propsFactory$z(test) + } - if (!isAncient && !isSecurityChange && !prUrlRegex.test(change["pr-url"])) { - file.message( - `changes[${index}]: PR-URL does not match the expected pattern`, - node - ); - } + if (typeof test === 'function') { + return castFactory$z(test) + } - if (typeof change.description !== "string" || !change.description.length) { - file.message( - `changes[${index}]: must contain a non-empty description`, - node - ); - } else if (!change.description.endsWith(".")) { - file.message( - `changes[${index}]: description must end with a period`, - node - ); + throw new Error('Expected function, string, or object as test') } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$A(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; - changesVersions.push( - Array.isArray(change.version) ? change.version[0] : change.version - ); + while (++index < tests.length) { + checks[index] = convert$D(tests[index]); } - if (areVersionsUnordered(changesVersions)) { - file.message("Items in `changes` list are not in order", node); + return castFactory$z(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } + + return false } } -function validateMeta(node, file, meta) { - switch (unorderedKeys(meta)) { - case kContainsIllegalKey: - file.message( - "YAML dictionary contains illegal keys. Accepted values are: " + - allowedKeys.join(", "), - node - ); - break; +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$z(check) { + return castFactory$z(all) - case kWrongKeyOrder: - file.message( - "YAML dictionary keys should be in this order: " + - allowedKeys.join(", "), - node - ); - break; - } + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; - if (containsInvalidVersionNumber(meta.added)) { - file.message(`Invalid \`added\` value: ${invalidVersionMessage}`, node); - } else if (areVersionsUnordered(meta.added)) { - file.message("Versions in `added` list are not in order", node); - } + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } - if (containsInvalidVersionNumber(meta.deprecated)) { - file.message( - `Invalid \`deprecated\` value: ${invalidVersionMessage}`, - node - ); - } else if (areVersionsUnordered(meta.deprecated)) { - file.message("Versions in `deprecated` list are not in order", node); + return true } +} - if (containsInvalidVersionNumber(meta.removed)) { - file.message(`Invalid \`removed\` value: ${invalidVersionMessage}`, node); - } else if (areVersionsUnordered(meta.removed)) { - file.message("Versions in `removed` list are not in order", node); +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$A(check) { + return castFactory$z(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check } +} - if ("changes" in meta) { - validateChanges(file, node, meta.changes); +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory$z(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) } } -function validateYAMLComments(tree, file) { - unistUtilVisit(tree, "html", function visitor(node) { - if (node.value.startsWith("".length)); +// Utility to return true. +function ok$B() { + return true +} - validateMeta(node, file, meta); - } catch (e) { - file.message(e, node); - } - }); +/** + * @param {string} d + * @returns {string} + */ +function color$B(d) { + return '\u001B[33m' + d + '\u001B[39m' } -var remarkLintNodejsYamlComments = unifiedLintRule("remark-lint:nodejs-yaml-comments", validateYAMLComments); +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ -var escapeStringRegexp$1 = string => { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); - } +/** + * Continue traversing as normal + */ +const CONTINUE$B = true; +/** + * Do not traverse this node’s children + */ +const SKIP$B = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$B = false; - // Escape characters with special meaning either inside or outside character sets. - // Use a simple backslash escape when it’s always valid, and a \unnnn escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. - return string - .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - .replace(/-/g, '\\x2d'); -}; +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$A = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } -const start$f = unistUtilPosition.start; + const is = convert$D(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$B(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } -var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); + return visit -function testProhibited (val, content) { - let regexpFlags = 'g'; - let no = val.no; + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; - if (!no) { - no = escapeStringRegexp$1(val.yes); - regexpFlags += 'i'; - } + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$A(visitor(node, parents)); - let regexpString = '(? -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); - regexpString += `(${no})`; + if (subresult[0] === EXIT$B) { + return subresult + } - if (ignoreNextTo) { - regexpString += `(?!${ignoreNextTo})`; - } + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } - // If it ends with a letter, make sure it is a word break. - if (/\b$/.test(no)) { - regexpString += '\\b'; + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$A(value) { + if (Array.isArray(value)) { + return value } - regexpString += '(?!\\.\\w)'; - const re = new RegExp(regexpString, regexpFlags); - const results = []; - let result = re.exec(content); - while (result) { - if (result[1] !== val.yes) { - results.push({ result: result[1], index: result.index }); - } - result = re.exec(content); + if (typeof value === 'number') { + return [CONTINUE$B, value] } - return results + return [value] } -function prohibitedStrings (ast, file, strings) { - const location = vfileLocation(file); - - unistUtilVisit(ast, 'text', checkText); +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ - function checkText (node) { - const content = node.value; - const initial = start$f(node).offset; +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$A = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - strings.forEach((val) => { - const results = testProhibited(val, content); - if (results.length) { - results.forEach(({ result, index }) => { - const message = val.yes ? `Use "${val.yes}" instead of "${result}"` : `Do not use "${result}"`; - file.message(message, { - start: location.toPoint(initial + index), - end: location.toPoint(initial + index + [...result].length) - }); - }); + visitParents$A(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) } - }); - } -} + } + ); /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module rule-style - * @fileoverview - * Warn when the thematic breaks (horizontal rules) violate a given or - * detected style. - * - * Options: `string`, either a corect thematic breaks such as `***`, or - * `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used thematic break style and warns when - * subsequent rules use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * has three settings that define how rules are created: - * - * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) - * (default: `*`) — Marker to use - * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) - * (default: `3`) — Number of markers to use - * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) - * (default: `true`) — Whether to pad markers with spaces - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md", "setting": "* * *"} - * - * * * * - * - * * * * - * - * @example {"name": "ok.md", "setting": "_______"} - * - * _______ - * - * _______ - * - * @example {"name": "not-ok.md", "label": "input"} - * - * *** - * - * * * * - * - * @example {"name": "not-ok.md", "label": "output"} + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point * - * 3:1-3:6: Rules should use `***` + * @typedef {Partial} PointLike * - * @example {"name": "not-ok.md", "label": "output", "setting": "💩", "config": {"positionless": true}} + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] * - * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` + * @typedef {Object} NodeLike + * @property {PositionLike} [position] */ -var rule = unifiedLintRule; - - - - -var remarkLintRuleStyle = rule('remark-lint:rule-style', ruleStyle); +var pointStart$p = point$s('start'); +var pointEnd$e = point$s('end'); -var start$g = unistUtilPosition.start; -var end$9 = unistUtilPosition.end; - -function ruleStyle(tree, file, option) { - var contents = String(file); - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; - - if (preferred !== null && /[^-_* ]/.test(preferred)) { - file.fail( - "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" - ); - } - - unistUtilVisit(tree, 'thematicBreak', visitor); - - function visitor(node) { - var initial = start$g(node).offset; - var final = end$9(node).offset; - var rule; +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$s(type) { + return point - if (!unistUtilGenerated(node)) { - rule = contents.slice(initial, final); + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; - if (preferred) { - if (rule !== preferred) { - file.message('Rules should use `' + preferred + '`', node); - } - } else { - preferred = rule; - } + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null } } } @@ -49921,476 +73832,685 @@ function ruleStyle(tree, file, option) { * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT - * @module strong-marker + * @module table-pipes * @fileoverview - * Warn for violating importance (strong) markers. - * - * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. - * - * `'consistent'` detects the first used importance style and warns when - * subsequent importance sequences use different styles. + * Warn when table rows are not fenced with pipes. * * ## Fix * * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats importance using an `*` (asterisk) by default. - * Pass - * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) - * to use `_` (underscore) instead. + * creates fenced rows with initial and final pipes by default. * * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) * on how to automatically fix warnings for this rule. * - * @example {"name": "ok.md"} - * - * **foo** and **bar**. - * - * @example {"name": "also-ok.md"} - * - * __foo__ and __bar__. - * - * @example {"name": "ok.md", "setting": "*"} - * - * **foo**. - * - * @example {"name": "ok.md", "setting": "_"} + * @example + * {"name": "ok.md", "gfm": true} * - * __foo__. - * - * @example {"name": "not-ok.md", "label": "input"} - * - * **foo** and __bar__. + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | * - * @example {"name": "not-ok.md", "label": "output"} + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} * - * 1:13-1:20: Strong should use `*` as a marker + * A | B + * ----- | ----- + * Alpha | Bravo * - * @example {"name": "not-ok.md", "label": "output", "setting": "💩", "config": {"positionless": true}} + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} * - * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` + * 1:1: Missing initial pipe in table fence + * 1:10: Missing final pipe in table fence + * 3:1: Missing initial pipe in table fence + * 3:14: Missing final pipe in table fence */ +const reasonStart = 'Missing initial pipe in table fence'; +const reasonEnd = 'Missing final pipe in table fence'; +const remarkLintTablePipes = lintRule$E( + 'remark-lint:table-pipes', + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$A(tree, 'table', (node) => { + let index = -1; + + while (++index < node.children.length) { + const row = node.children[index]; + const start = pointStart$p(row); + const end = pointEnd$e(row); + + if ( + typeof start.offset === 'number' && + value.charCodeAt(start.offset) !== 124 + ) { + file.message(reasonStart, start); + } + if ( + typeof end.offset === 'number' && + value.charCodeAt(end.offset - 1) !== 124 + ) { + file.message(reasonEnd, end); + } + } + }); + } +); +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap$G(middleware, callback) { + /** @type {boolean} */ + let called; -var remarkLintStrongMarker = unifiedLintRule('remark-lint:strong-marker', strongMarker); + return wrapped -var markers$1 = {'*': true, _: true, null: true}; + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; -function strongMarker(tree, file, option) { - var contents = String(file); - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; + if (fnExpectsCallback) { + parameters.push(done); + } - if (markers$1[preferred] !== true) { - file.fail( - 'Incorrect strong marker `' + - preferred + - "`: use either `'consistent'`, `'*'`, or `'_'`" - ); - } + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; - unistUtilVisit(tree, 'strong', visitor); + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } - function visitor(node) { - var marker = contents.charAt(unistUtilPosition.start(node).offset); + return done(exception) + } - if (!unistUtilGenerated(node)) { - if (preferred) { - if (marker !== preferred) { - file.message( - 'Strong should use `' + preferred + '` as a marker', - node - ); - } + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); } else { - preferred = marker; + then(result); } } } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-cell-padding - * @fileoverview - * Warn when table cells are incorrectly padded. - * - * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. - * - * `'consistent'` detects the first used cell padding style and warns when - * subsequent cells use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats tables with padding by default. - * Pass - * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) - * to not use padding. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md", "setting": "padded", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} - * - * | A | B | - * | :----|----: | - * | Alpha|Bravo | - * - * | C | D | - * | :----- | ---: | - * |Charlie | Delta| - * - * Too much padding isn’t good either: - * - * | E | F | G | H | - * | :---- | -------- | :----: | -----: | - * | Echo | Foxtrot | Golf | Hotel | - * - * @example {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:8: Cell should be padded - * 3:9: Cell should be padded - * 7:2: Cell should be padded - * 7:17: Cell should be padded - * 13:9: Cell should be padded with 1 space, not 2 - * 13:20: Cell should be padded with 1 space, not 2 - * 13:21: Cell should be padded with 1 space, not 2 - * 13:29: Cell should be padded with 1 space, not 2 - * 13:30: Cell should be padded with 1 space, not 2 - * - * @example {"name": "ok.md", "setting": "compact", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * @example {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} - * - * | A | B | - * | -----| -----| - * | Alpha| Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} - * - * 3:2: Cell should be compact - * 3:11: Cell should be compact - * 7:16: Cell should be compact - * - * @example {"name": "ok-padded.md", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | ------- | ----- | - * | Charlie | Delta | - * - * @example {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | :----- | ----: | - * |Charlie | Delta | + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile * - * @example {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple * - * 7:2: Cell should be padded - * - * @example {"name": "ok-compact.md", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C |D | - * |-------|-----| - * |Charlie|Delta| - * - * @example {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} - * - * 7:16: Cell should be compact - * - * @example {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} - * - * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` - * - * @example {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} - * - * - * - * | | Alpha | Bravo| - * | ------ | ----- | ---: | - * | Charlie| | Echo| - * - * @example {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:25: Cell should be padded - * 5:10: Cell should be padded - * 5:25: Cell should be padded - * - * @example {"name": "missing-body.md", "setting": "padded", "gfm": true} - * - * - * - * | Alpha | Bravo | Charlie | - * | ----- | ------- | ------- | - * | Delta | - * | Echo | Foxtrot | + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} */ +const primitives$F = new Set(['string', 'number', 'boolean']); +/** + * @param {string} id + * @param {Rule} rule + */ +function lintRule$F(id, rule) { + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + Object.defineProperty(plugin, 'name', {value: id}); + return plugin + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$G(ruleId, raw); -var remarkLintTableCellPadding = unifiedLintRule('remark-lint:table-cell-padding', tableCellPadding); - -var start$h = unistUtilPosition.start; -var end$a = unistUtilPosition.end; - -var styles$4 = {null: true, padded: true, compact: true}; - -function tableCellPadding(tree, file, option) { - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; + if (!severity) return - if (styles$4[preferred] !== true) { - file.fail( - 'Incorrect table cell padding style `' + - preferred + - "`, expected `'padded'`, `'compact'`, or `'consistent'`" - ); - } + const fatal = severity === 2; - unistUtilVisit(tree, 'table', visitor); + return (tree, file, next) => { + let index = file.messages.length - 1; - function visitor(node) { - var rows = node.children; - var sizes = new Array(node.align.length); - var length = unistUtilGenerated(node) ? -1 : rows.length; - var index = -1; - var entries = []; - var style; - var row; - var cells; - var column; - var cellCount; - var cell; - var entry; - var contentStart; - var contentEnd; + wrap$G(rule, (error) => { + const messages = file.messages; - // Check rows. - while (++index < length) { - row = rows[index]; - cells = row.children; - cellCount = cells.length; - column = -1; - - // Check fences (before, between, and after cells). - while (++column < cellCount) { - cell = cells[column]; - - if (cell && cell.children.length !== 0) { - contentStart = start$h(cell.children[0]).offset; - contentEnd = end$a(cell.children[cell.children.length - 1]).offset; - - entries.push({ - node: cell, - start: contentStart - start$h(cell).offset - (column ? 0 : 1), - end: end$a(cell).offset - contentEnd - 1, - column: column - }); + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } - // Detect max space per column. - sizes[column] = Math.max( - sizes[column] || 0, - contentEnd - contentStart - ); + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal}); } - } - } - if (preferred) { - style = preferred === 'padded' ? 1 : 0; - } else { - style = entries[0] && (!entries[0].start || !entries[0].end) ? 0 : 1; + next(); + })(tree, file, options); } + } +} - index = -1; - length = entries.length; +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$G(name, value) { + /** @type {unknown[]} */ + let result; - while (++index < length) { - entry = entries[index]; - checkSide('start', entry, style, sizes); - checkSide('end', entry, style, sizes); + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives$F.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; } + } - return unistUtilVisit.SKIP + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) } - function checkSide(side, entry, style, sizes) { - var cell = entry.node; - var spacing = entry[side]; - var column = entry.column; - var reason; - var point; + result[0] = level; - if (spacing === undefined || spacing === style) { - return - } + // @ts-expect-error: it’s now a valid tuple. + return result +} - reason = 'Cell should be '; +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ - if (style === 0) { - // Ignore every cell except the biggest in the column. - if (size$1(cell) < sizes[column]) { - return +const convert$E = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok$C } - reason += 'compact'; - } else { - reason += 'padded'; + if (typeof test === 'string') { + return typeFactory$B(test) + } - if (spacing > style) { - // May be right or center aligned. - if (size$1(cell) < sizes[column]) { - return - } + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory$B(test) : propsFactory$A(test) + } - reason += ' with 1 space, not ' + spacing; + if (typeof test === 'function') { + return castFactory$A(test) } + + throw new Error('Expected function, string, or object as test') } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory$B(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; - if (side === 'start') { - point = start$h(cell); - if (!column) { - point.column++; - point.offset++; - } - } else { - point = end$a(cell); - point.column--; - point.offset--; + while (++index < tests.length) { + checks[index] = convert$E(tests[index]); + } + + return castFactory$A(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true } - file.message(reason, point); + return false } } -function size$1(node) { - return ( - end$a(node.children[node.children.length - 1]).offset - - start$h(node.children[0]).offset - ) +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory$A(check) { + return castFactory$A(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } } /** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-pipes - * @fileoverview - * Warn when table rows are not fenced with pipes. + * Utility to convert a string into a function which checks a given node’s type + * for said string. * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * creates fenced rows with initial and final pipes by default. - * Pass - * [`looseTable: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsloosetable) - * to not use row fences. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example {"name": "ok.md", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example {"name": "not-ok.md", "label": "input", "gfm": true} - * - * A | B - * ----- | ----- - * Alpha | Bravo - * - * @example {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1: Missing initial pipe in table fence - * 1:10: Missing final pipe in table fence - * 3:1: Missing initial pipe in table fence - * 3:14: Missing final pipe in table fence + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory$B(check) { + return castFactory$A(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} */ +function castFactory$A(check) { + return assertion + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} +// Utility to return true. +function ok$C() { + return true +} +/** + * @param {string} d + * @returns {string} + */ +function color$C(d) { + return '\u001B[33m' + d + '\u001B[39m' +} +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ +/** + * Continue traversing as normal + */ +const CONTINUE$C = true; +/** + * Do not traverse this node’s children + */ +const SKIP$C = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$C = false; -var remarkLintTablePipes = unifiedLintRule('remark-lint:table-pipes', tablePipes); +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$B = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } -var start$i = unistUtilPosition.start; -var end$b = unistUtilPosition.end; + const is = convert$E(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$C(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } -var reasonStart = 'Missing initial pipe in table fence'; -var reasonEnd = 'Missing final pipe in table fence'; + return visit -function tablePipes(tree, file) { - var contents = String(file); + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; - unistUtilVisit(tree, 'table', visitor); + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$B(visitor(node, parents)); - function visitor(node) { - var rows = node.children; - var length = rows.length; - var index = -1; - var row; + if (result[0] === EXIT$C) { + return result + } + } - while (++index < length) { - row = rows[index]; + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$C) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); - if (!unistUtilGenerated(row)) { - if (contents.charCodeAt(start$i(row).offset) !== 124) { - file.message(reasonStart, start$i(row)); - } + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$C) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } - if (contents.charCodeAt(end$b(row).offset - 1) !== 124) { - file.message(reasonEnd, end$b(row)); + return result } } } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$B(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$C, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$B = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$B(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart$q = point$t('start'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point$t(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } } } @@ -50419,7 +74539,8 @@ function tablePipes(tree, file) { * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) * on how to automatically fix warnings for this rule. * - * @example {"name": "ok.md"} + * @example + * {"name": "ok.md"} * * By default (`'consistent'`), if the file uses only one marker, * that’s OK. @@ -50434,109 +74555,94 @@ function tablePipes(tree, file) { * 2. Bar * 3. Baz * - * @example {"name": "ok.md", "setting": "*"} + * @example + * {"name": "ok.md", "setting": "*"} * * * Foo * - * @example {"name": "ok.md", "setting": "-"} + * @example + * {"name": "ok.md", "setting": "-"} * * - Foo * - * @example {"name": "ok.md", "setting": "+"} + * @example + * {"name": "ok.md", "setting": "+"} * * + Foo * - * @example {"name": "not-ok.md", "label": "input"} + * @example + * {"name": "not-ok.md", "label": "input"} * * * Foo * - Bar * + Baz * - * @example {"name": "not-ok.md", "label": "output"} + * @example + * {"name": "not-ok.md", "label": "output"} * * 2:1-2:6: Marker style should be `*` * 3:1-3:6: Marker style should be `*` * - * @example {"name": "not-ok.md", "label": "output", "setting": "💩", "config": {"positionless": true}} + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} * * 1:1: Incorrect unordered list item marker style `💩`: use either `'-'`, `'*'`, or `'+'` */ +const markers = new Set(['-', '*', '+']); - - - - -var remarkLintUnorderedListMarkerStyle = unifiedLintRule( +const remarkLintUnorderedListMarkerStyle = lintRule$F( 'remark-lint:unordered-list-marker-style', - unorderedListMarkerStyle -); - -var start$j = unistUtilPosition.start; - -var styles$5 = { - '-': true, - '*': true, - '+': true, - null: true -}; - -function unorderedListMarkerStyle(tree, file, option) { - var contents = String(file); - var preferred = - typeof option === 'string' && option !== 'consistent' ? option : null; - - if (styles$5[preferred] !== true) { - file.fail( - 'Incorrect unordered list item marker style `' + - preferred + - "`: use either `'-'`, `'*'`, or `'+'`" - ); - } + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && !markers.has(option)) { + file.fail( + 'Incorrect unordered list item marker style `' + + option + + "`: use either `'-'`, `'*'`, or `'+'`" + ); + } - unistUtilVisit(tree, 'list', visitor); + visit$B(tree, 'list', (node) => { + if (node.ordered) return - function visitor(node) { - var children = node.children; - var length = node.ordered ? 0 : children.length; - var index = -1; - var child; - var marker; + let index = -1; - while (++index < length) { - child = children[index]; + while (++index < node.children.length) { + const child = node.children[index]; - if (!unistUtilGenerated(child)) { - marker = contents - .slice(start$j(child).offset, start$j(child.children[0]).offset) - .replace(/\[[x ]?]\s*$/i, '') - .replace(/\s/g, ''); + if (!generated(child)) { + const marker = /** @type {Marker} */ ( + value + .slice( + pointStart$q(child).offset, + pointStart$q(child.children[0]).offset + ) + .replace(/\[[x ]?]\s*$/i, '') + .replace(/\s/g, '') + ); - if (preferred) { - if (marker !== preferred) { - file.message('Marker style should be `' + preferred + '`', child); + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Marker style should be `' + option + '`', child); } - } else { - preferred = marker; } } - } + }); } -} +); + +// @see https://github.com/nodejs/node/blob/master/doc/guides/doc-style-guide.md // Add in rules alphabetically -var plugins$2 = [ - remarkLint, +const remarkPresetLintNode = [ // Leave preset at the top so it can be overridden remarkPresetLintRecommended, [remarkLintBlockquoteIndentation, 2], - [ - remarkLintCheckboxCharacterStyle, - { - checked: "x", - unchecked: " ", - }, - ], + [remarkLintCheckboxCharacterStyle, { checked: "x", unchecked: " " }], remarkLintCheckboxContentIndent, [remarkLintCodeBlockStyle, "fenced"], remarkLintDefinitionSpacing, @@ -50572,7 +74678,7 @@ var plugins$2 = [ remarkLintNoConsecutiveBlankLines, remarkLintNoFileNameArticles, remarkLintNoFileNameConsecutiveDashes, - remarkLintNoFileNameOuterDashes, + remarkLintNofileNameOuterDashes, remarkLintNoHeadingIndent, remarkLintNoMultipleToplevelHeadings, remarkLintNoShellDollars, @@ -50607,9 +74713,10 @@ var plugins$2 = [ [remarkLintUnorderedListMarkerStyle, "*"], ]; -var remarkPresetLintNode = { - plugins: plugins$2 -}; +var remarkPresetLintNode$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + 'default': remarkPresetLintNode +}); var www = {tokenize: tokenizeWww}; var http = {tokenize: tokenizeHttp}; @@ -52261,7 +76368,7 @@ var fromMarkdown$4 = { exit: exit$4 }; -var own$6 = {}.hasOwnProperty; +var own$a = {}.hasOwnProperty; var fromMarkdown$5 = configure$4([ fromMarkdown$1, @@ -52288,7 +76395,7 @@ function extension$3(config, extension) { var right; for (key in extension) { - left = own$6.call(config, key) ? config[key] : (config[key] = {}); + left = own$a.call(config, key) ? config[key] : (config[key] = {}); right = extension[key]; if (key === 'canContainEols') { @@ -52783,6 +76890,8 @@ function gfm(options) { } } +var lintNode = /*@__PURE__*/getAugmentedNamespace(remarkPresetLintNode$1); + // To aid in future maintenance, this layout closely matches remark-cli/cli.js. // https://github.com/remarkjs/remark/blob/master/packages/remark-cli/cli.js @@ -52795,7 +76904,7 @@ function gfm(options) { unifiedArgs({ - processor: remark().use(remarkGfm).use(remarkPresetLintNode), + processor: remark().use(remarkGfm).use(lintNode), name: proc.name, description: cli.description, version: [ diff --git a/tools/node-lint-md-cli-rollup/package-lock.json b/tools/node-lint-md-cli-rollup/package-lock.json index 6f13ecea4c2cc9..d402d31acd58f0 100644 --- a/tools/node-lint-md-cli-rollup/package-lock.json +++ b/tools/node-lint-md-cli-rollup/package-lock.json @@ -5,13 +5,14 @@ "requires": true, "packages": { "": { + "name": "node-lint-md-cli-rollup", "version": "2.0.2", "dependencies": { "markdown-extensions": "^1.1.1", "remark": "^13.0.0", "remark-gfm": "^1.0.0", "remark-lint": "^8.0.0", - "remark-preset-lint-node": "^2.3.0", + "remark-preset-lint-node": "^3.0.0", "unified-args": "^8.1.0" }, "devDependencies": { @@ -191,6 +192,14 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "node_modules/@types/hast": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.2.tgz", + "integrity": "sha512-Op5W7jYgZI7AWKY5wQ0/QNMzQM7dGQPyW1rXKNiymVCy5iTfdPuGu4HhYNOM2sIv8gUfIuIdcYlXmAepwaowow==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mdast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", @@ -205,6 +214,11 @@ "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", "dev": true }, + "node_modules/@types/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==" + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -328,6 +342,15 @@ "node": ">=6" } }, + "node_modules/ccount": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", + "integrity": "sha512-VOR0NWFYX65n9gELQdcpqsie5L5ihBXuZGAgaPEp/U7IOSjnPMEH6geE+2f6lcekaNEfWzAHS45mPvSo5bqsUA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -349,6 +372,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/character-entities-html4": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.0.0.tgz", + "integrity": "sha512-dwT2xh5ZhUAjyP96k57ilMKoTQyASaw9IAMR9U5c1lCu2RUni6O6jxfpUEdO2RcPT6TJFvr8pqsbami4Jk+2oA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", @@ -405,15 +437,6 @@ "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, - "node_modules/collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -430,6 +453,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", + "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -672,6 +704,167 @@ "node": ">=8" } }, + "node_modules/hast-util-from-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz", + "integrity": "sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.1.tgz", + "integrity": "sha512-ag0fiZfRWsPiR1udvnSbaazJLGv8qd8E+/e3rW8rUZhbKG4HNJmFL4QkEceN+22BgE+uozXY30z/s+2dL6Z++g==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz", + "integrity": "sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.1.tgz", + "integrity": "sha512-S1mTqXvWVGIxrWw0xOHHvmevwCBFTRGNvXWsjE32IyEAlMhbMkK+ZuP6CAqkQ6Vb7swrehaHpfXHEI6voGDh0w==", + "dependencies": { + "@types/hast": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", + "integrity": "sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", + "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", + "integrity": "sha512-4OYzQQsBt0G9bJ/nM9/DDsjm4+fVdzAaPJJcWk5QwA3GIAPxQEeOR0rsI8HbDHQz5Gta8pVvGnnTNSbZVEVvkQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -1074,9 +1267,12 @@ } }, "node_modules/mdast-util-heading-style": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", - "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-2.0.0.tgz", + "integrity": "sha512-q9+WW2hJduW51LgV2r/fcU5wIt2GLFf0yYHxyi0f2aaxnC63ErBSOAJlhP6nbQ6yeG5rTCozbwOi4QNDPKV0zw==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -1201,6 +1397,39 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", + "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz", + "integrity": "sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1305,6 +1534,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -1322,9 +1556,9 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/picomatch": { @@ -1346,6 +1580,15 @@ "node": ">=4" } }, + "node_modules/property-information": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.0.1.tgz", + "integrity": "sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1382,2723 +1625,12735 @@ "node": ">= 0.10" } }, - "node_modules/remark": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", - "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "node_modules/rehype": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", + "integrity": "sha512-gZcttmf9R5IYHb8AlI1rlmWqXS1yX0rSB/S5ZGJs8atfYZy2DobvH3Ic/gSzB+HL/+oOHPtBguw1TprfhxXBgQ==", "dependencies": { - "remark-parse": "^9.0.0", - "remark-stringify": "^9.0.0", - "unified": "^9.1.0" + "@types/hast": "^2.0.0", + "rehype-parse": "^8.0.0", + "rehype-stringify": "^9.0.0", + "unified": "^10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-gfm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", - "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "node_modules/rehype-parse": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.2.tgz", + "integrity": "sha512-Y5AvUbTareuAcCQITTbC9SGagm1IvOOSfG5CTTaOUW0pEeoNHkOq4YmMaEywUmSwwOgel3gOF3O7Mwl1acoBzg==", "dependencies": { - "mdast-util-gfm": "^0.1.0", - "micromark-extension-gfm": "^0.3.0" + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-8.0.0.tgz", - "integrity": "sha512-ESI8qJQ/TIRjABDnqoFsTiZntu+FRifZ5fJ77yX63eIDijl/arvmDvT+tAf75/Nm5BFL4R2JFUtkHRGVjzYUsg==", - "dependencies": { - "remark-message-control": "^6.0.0" - }, + "node_modules/rehype-parse/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-lint-blockquote-indentation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-2.0.1.tgz", - "integrity": "sha512-uJ9az/Ms9AapnkWpLSCJfawBfnBI2Tn1yUsPNqIFv6YM98ymetItUMyP6ng9NFPqDvTQBbiarulkgoEo0wcafQ==", - "dependencies": { - "mdast-util-to-string": "^1.0.2", - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/rehype-parse/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/remark-lint-blockquote-indentation/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "node_modules/rehype-parse/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-lint-checkbox-character-style": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-3.0.0.tgz", - "integrity": "sha512-691OJ5RdBRXVpvnOEiBhMB4uhHJSHVttw83O4qyAkNBiqxa1Axqhsz8FgmzYgRLQbOGd2ncVUcXG1LOJt6C0DQ==", + "node_modules/rehype-parse/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-checkbox-content-indent": { + "node_modules/rehype-parse/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-3.0.0.tgz", - "integrity": "sha512-+T4+hoY85qZE2drD2rCe14vF7fAgD3Kv2fkFd1HRvv3M5Riy148w/4YeoBI5U5BpybGTVUeEUYLCeJ8zbJLjkw==", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-code-block-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-2.0.1.tgz", - "integrity": "sha512-eRhmnColmSxJhO61GHZkvO67SpHDshVxs2j3+Zoc5Y1a4zQT2133ZAij04XKaBFfsVLjhbY/+YOWxgvtjx2nmA==", + "node_modules/rehype-parse/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-definition-spacing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-2.0.1.tgz", - "integrity": "sha512-xK9DOQO5MudITD189VyUiMHBIKltW1oc55L7Fti3i9DedXoBG7Phm+V9Mm7IdWzCVkquZVgVk63xQdqzSQRrSQ==", + "node_modules/rehype-parse/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-fenced-code-flag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-2.0.1.tgz", - "integrity": "sha512-+COnWHlS/h02FMxoZWxNlZW3Y8M0cQQpmx3aNCbG7xkyMyCKsMLg9EmRvYHHIbxQCuF3JT0WWx5AySqlc7d+NA==", + "node_modules/rehype-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.1.tgz", + "integrity": "sha512-xfhm8Erp7yL+RRgYmtZMJUqu6OSguwOQMfR2LkqT1dgNDQheClFMaDPVERy4/su7o0eHo0PKFGn4L68kOjVdRQ==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/hast": "^2.0.0", + "hast-util-to-html": "^8.0.0", + "unified": "^10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-fenced-code-marker": { + "node_modules/rehype-stringify/node_modules/bail": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-2.0.1.tgz", - "integrity": "sha512-lujpjm04enn3ma6lITlttadld6eQ1OWAEcT3qZzvFHp+zPraC0yr0eXlvtDN/0UH8mrln/QmGiZp3i8IdbucZg==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-lint-file-extension": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.5.tgz", - "integrity": "sha512-oVQdf5vEomwHkfQ7R/mgmsWW2H/t9kSvnrxtVoNOHr+qnOEafKKDn+AFhioN2kqtjCZBAjSSrePs6xGKmXKDTw==", - "dependencies": { - "unified-lint-rule": "^1.0.0" + "node_modules/rehype-stringify/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/remark-lint-final-definition": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-2.1.0.tgz", - "integrity": "sha512-83K7n2icOHPfBzbR5Mr1o7cu8gOjD8FwJkFx/ly+rW+8SHfjCj4D3WOFGQ1xVdmHjfomBDXXDSNo2oiacADVXQ==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, + "node_modules/rehype-stringify/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-lint-final-newline": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.5.tgz", - "integrity": "sha512-rfLlW8+Fz2dqnaEgU4JwLA55CQF1T4mfSs/GwkkeUCGPenvEYwSkCN2KO2Gr1dy8qPoOdTFE1rSufLjmeTW5HA==", + "node_modules/rehype-stringify/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "unified-lint-rule": "^1.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-first-heading-level": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-2.0.1.tgz", - "integrity": "sha512-XoK/eLfnz1VSA8QkfMbdbvlCqOwgw29MAWEGC4Cv0666nTcY9uWHlZ/SV/20YNmuEVdfCA+92v92mM486qcASQ==", + "node_modules/rehype-stringify/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-hard-break-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.1.tgz", - "integrity": "sha512-Qfn/BMQFamHhtbfLrL8Co/dbYJFLRL4PGVXZ5wumkUO5f9FkZC2RsV+MD9lisvGTkJK0ZEJrVVeaPbUIFM0OAw==", + "node_modules/rehype-stringify/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-heading-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-2.0.1.tgz", - "integrity": "sha512-IrFLNs0M5Vbn9qg51AYhGUfzgLAcDOjh2hFGMz3mx664dV6zLcNZOPSdJBBJq3JQR4gKpoXcNwN1+FFaIATj+A==", + "node_modules/rehype-stringify/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "mdast-util-heading-style": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-list-item-bullet-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-3.0.0.tgz", - "integrity": "sha512-X2rleWP8XReC4LXKF7Qi5vYiPJkA4Grx5zxsjHofFrVRz6j0PYOCuz7vsO+ZzMunFMfom6FODnscSWz4zouDVw==", + "node_modules/rehype/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rehype/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-list-item-indent": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.1.tgz", - "integrity": "sha512-4IKbA9GA14Q9PzKSQI6KEHU/UGO36CSQEjaDIhmb9UOhyhuzz4vWhnSIsxyI73n9nl9GGRAMNUSGzr4pQUFwTA==", + "node_modules/rehype/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-maximum-line-length": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-2.0.3.tgz", - "integrity": "sha512-zyWHBFh1oPAy+gkaVFXiTHYP2WwriIeBtaarDqkweytw0+qmuikjVMJTWbQ3+XfYBreD7KKDM9SI79nkp0/IZQ==", + "node_modules/rehype/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-auto-link-without-protocol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.1.tgz", - "integrity": "sha512-TFcXxzucsfBb/5uMqGF1rQA+WJJqm1ZlYQXyvJEXigEZ8EAxsxZGPb/gOQARHl/y0vymAuYxMTaChavPKaBqpQ==", + "node_modules/rehype/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "node_modules/remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "dependencies": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-blockquote-without-marker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-4.0.0.tgz", - "integrity": "sha512-Y59fMqdygRVFLk1gpx2Qhhaw5IKOR9T38Wf7pjR07bEFBGUNfcoNVIFMd1TCJfCPQxUyJzzSqfZz/KT7KdUuiQ==", + "node_modules/remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-consecutive-blank-lines": { + "node_modules/remark-lint": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-8.0.0.tgz", + "integrity": "sha512-ESI8qJQ/TIRjABDnqoFsTiZntu+FRifZ5fJ77yX63eIDijl/arvmDvT+tAf75/Nm5BFL4R2JFUtkHRGVjzYUsg==", + "dependencies": { + "remark-message-control": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-blockquote-indentation": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-3.0.0.tgz", - "integrity": "sha512-kmzLlOLrapBKEngwYFTdCZDmeOaze6adFPB7G0EdymD9V1mpAlnneINuOshRLEDKK5fAhXKiZXxdGIaMPkiXrA==", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.0.tgz", + "integrity": "sha512-qWWyAJWHwnVFsfKEyl51os1rr4ex9KX398g8326esJ2/RFsCYJbJaXmVk/S+uf7B7HfOWFuJo+tu/7jlZZ54+Q==", "dependencies": { + "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-duplicate-definitions": { + "node_modules/remark-lint-blockquote-indentation/node_modules/bail": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.1.tgz", - "integrity": "sha512-XL22benJZB01m+aOse91nsu1IMFqeWJWme9QvoJuxIcBROO1BG1VoqLOkwNcawE/M/0CkvTo5rfx0eMlcnXOIw==", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-blockquote-indentation/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-blockquote-indentation/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-blockquote-indentation/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-file-name-articles": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.5.tgz", - "integrity": "sha512-AQk5eTb3s3TAPPjiglZgqlQj4ycao+gPs8/XkdN1VCPUtewW0GgwoQe7YEuBKayJ6ioN8dGP37Kg/P/PlKaRQA==", + "node_modules/remark-lint-blockquote-indentation/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { - "unified-lint-rule": "^1.0.0" + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-file-name-consecutive-dashes": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.5.tgz", - "integrity": "sha512-Mg2IDsi790/dSdAzwnBnsMYdZm3qC2QgGwqOWcr0TPABJhhjC3p8r5fX4MNMTXI5It7B7bW9+ImmCeLOZiXkLg==", - "dependencies": { - "unified-lint-rule": "^1.0.0" - }, + "node_modules/remark-lint-blockquote-indentation/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-file-name-outer-dashes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.6.tgz", - "integrity": "sha512-rT8CmcIlenegS0Yst4maYXdZfqIjBOiRUY8j/KJkORF5tKH+3O1/S07025qPGmcRihzK3w4yO0K8rgkKQw0b9w==", - "dependencies": { - "unified-lint-rule": "^1.0.0" - }, + "node_modules/remark-lint-blockquote-indentation/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-heading-content-indent": { + "node_modules/remark-lint-blockquote-indentation/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-3.0.0.tgz", - "integrity": "sha512-yULDoVSIqKylLDfW6mVUbrHlyEWUSFtVFiKc+/BA412xDIhm8HZLUnP+FsuBC0OzbIZ+bO9Txy52WtO3LGnK1A==", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "mdast-util-heading-style": "^1.0.2", - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-heading-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-3.0.0.tgz", - "integrity": "sha512-b8ImhLv2AnRDxtYUODplzsl/7IwQ+lqRmD1bwbZgSerEP9MLaULW3SjH37EyA6z+8rCDjvEyppKKU6zec0TCjg==", + "node_modules/remark-lint-blockquote-indentation/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", "dependencies": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-inline-padding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-3.0.0.tgz", - "integrity": "sha512-3s9uW3Yux9RFC0xV81MQX3bsYs+UY7nPnRuMxeIxgcVwxQ4E/mTJd9QjXUwBhU9kdPtJ5AalngdmOW2Tgar8Cg==", + "node_modules/remark-lint-blockquote-indentation/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", "dependencies": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-inline-padding/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "node_modules/remark-lint-blockquote-indentation/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-literal-urls": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.1.tgz", - "integrity": "sha512-IDdKtWOMuKVQIlb1CnsgBoyoTcXU3LppelDFAIZePbRPySVHklTtuK57kacgU5grc7gPM04bZV96eliGrRU7Iw==", + "node_modules/remark-lint-blockquote-indentation/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-literal-urls/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "node_modules/remark-lint-checkbox-character-style": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.0.tgz", + "integrity": "sha512-NHpVZOcTJeLOI1gGOvVDz8i3sXVY3s9K+OADupEA89Syfs4YAbnrij8OMJ6ozbHTn4av/HyVfsF4IK8X2pBUeQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-multiple-toplevel-headings": { + "node_modules/remark-lint-checkbox-character-style/node_modules/bail": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-2.0.1.tgz", - "integrity": "sha512-VKSItR6c+u3OsE5pUiSmNusERNyQS9Nnji26ezoQ1uvy06k3RypIjmzQqJ/hCkSiF+hoyC3ibtrrGT8gorzCmQ==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^2.0.0" + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-checkbox-character-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/remark-lint-no-shell-dollars": { + "node_modules/remark-lint-checkbox-character-style/node_modules/trough": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-2.0.2.tgz", - "integrity": "sha512-zhkHZOuyaD3r/TUUkkVqW0OxsR9fnSrAnHIF63nfJoAAUezPOu8D1NBsni6rX8H2DqGbPYkoeWrNsTwiKP0yow==", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-checkbox-character-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-shortcut-reference-image": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.1.tgz", - "integrity": "sha512-2jcZBdnN6ecP7u87gkOVFrvICLXIU5OsdWbo160FvS/2v3qqqwF2e/n/e7D9Jd+KTq1mR1gEVVuTqkWWuh3cig==", + "node_modules/remark-lint-checkbox-character-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-shortcut-reference-link": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.1.tgz", - "integrity": "sha512-pTZbslG412rrwwGQkIboA8wpBvcjmGFmvugIA+UQR+GfFysKtJ5OZMPGJ98/9CYWjw9Z5m0/EktplZ5TjFjqwA==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" - }, + "node_modules/remark-lint-checkbox-character-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-table-indentation": { + "node_modules/remark-lint-checkbox-character-style/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-checkbox-character-style/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-3.0.0.tgz", - "integrity": "sha512-+l7GovI6T+3LhnTtz/SmSRyOb6Fxy6tmaObKHrwb/GAebI/4MhFS1LVo3vbiP/RpPYtyQoFbbuXI55hqBG4ibQ==", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-tabs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-2.0.1.tgz", - "integrity": "sha512-Fy5fMKNA8AsfhRtxyxBnHlGMpDDfns9VSSYv00RiC96qwRD82VhDRM3tYWZRBBxE+j71t6g47x9o/poGC7PThQ==", + "node_modules/remark-lint-checkbox-character-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "vfile-location": "^3.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-trailing-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-trailing-spaces/-/remark-lint-no-trailing-spaces-2.0.1.tgz", - "integrity": "sha512-cj8t+nvtO6eAY2lJC7o5du8VeOCK13XiDUHL4U6k5aw6ZLr3EYWbQ/rNc6cr60eHkh5Ldm09KiZjV3CWpxqJ0g==", + "node_modules/remark-lint-checkbox-character-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", "dependencies": { - "unified-lint-rule": "^1.0.2" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-undefined-references": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-3.0.0.tgz", - "integrity": "sha512-0hzaJS9GuzSQVOeeNdJr/s66LRQOzp618xuOQPYWHcJdd+SCaRTyWbjMrTM/cCI5L1sYjgurp410NkIBQ32Vqg==", + "node_modules/remark-lint-checkbox-character-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "collapse-white-space": "^1.0.4", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.1.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.1.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-no-unused-definitions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.1.tgz", - "integrity": "sha512-+BMc0BOjc364SvKYLkspmxDch8OaKPbnUGgQBvK0Bmlwy42baR4C9zhwAWBxm0SBy5Z4AyM4G4jKpLXPH40Oxg==", + "node_modules/remark-lint-checkbox-character-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-ordered-list-marker-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.1.tgz", - "integrity": "sha512-Cnpw1Dn9CHn+wBjlyf4qhPciiJroFOEGmyfX008sQ8uGoPZsoBVIJx76usnHklojSONbpjEDcJCjnOvfAcWW1A==", + "node_modules/remark-lint-checkbox-content-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.0.tgz", + "integrity": "sha512-WeB8aSC1oesu0t/wcqNEbn3bg0kRw+NK7Y5xrhQsREw6NcH1TnvjH95PvizFT5LxXAGhz4AtCFz0B28YugSznQ==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-prohibited-strings": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-2.0.0.tgz", - "integrity": "sha512-N94RTdAT4qmYNBczNZEZbnpGvtl9GiLPO/xdG569IpbbtNFh5l+Nf5Mx5B1VeJMC8/hAR7wShag03Zf29MOO6Q==", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "unified-lint-rule": "^1.0.2", - "unist-util-position": "^3.1.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.1" + "node_modules/remark-lint-checkbox-content-indent/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-lint-rule-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-2.0.1.tgz", - "integrity": "sha512-hz4Ff9UdlYmtO6Czz99WJavCjqCer7Cav4VopXt+yVIikObw96G5bAuLYcVS7hvMUGqC9ZuM02/Y/iq9n8pkAg==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-checkbox-content-indent/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/remark-lint-strong-marker": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-2.0.1.tgz", - "integrity": "sha512-8X2IsW1jZ5FmW9PLfQjkL0OVy/J3xdXLcZrG1GTeQKQ91BrPFyEZqUM2oM6Y4S6LGtxWer+neZkPZNroZoRPBQ==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-checkbox-content-indent/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-table-cell-padding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-3.0.0.tgz", - "integrity": "sha512-sEKrbyFZPZpxI39R8/r+CwUrin9YtyRwVn0SQkNQEZWZcIpylK+bvoKIldvLIXQPob+ZxklL0GPVRzotQMwuWQ==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-table-pipes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-3.0.0.tgz", - "integrity": "sha512-QPokSazEdl0Y8ayUV9UB0Ggn3Jos/RAQwIo0z1KDGnJlGDiF80Jc6iU9RgDNUOjlpQffSLIfSVxH5VVYF/K3uQ==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, + "node_modules/remark-lint-checkbox-content-indent/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-lint-unordered-list-marker-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-2.0.1.tgz", - "integrity": "sha512-8KIDJNDtgbymEvl3LkrXgdxPMTOndcux3BHhNGB2lU4UnxSpYeHsxcDgirbgU6dqCAfQfvMjPvfYk19QTF9WZA==", - "dependencies": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, + "node_modules/remark-lint-checkbox-content-indent/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-message-control": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", - "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "mdast-comment-marker": "^1.0.0", - "unified-message-control": "^3.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", "dependencies": { - "mdast-util-from-markdown": "^0.8.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-preset-lint-node": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-2.4.1.tgz", - "integrity": "sha512-lNRqQulYuu8ADd4lSNhjOnZck/iDzLVY8oWA9U4BptfHQcDVwFm3bkNDfsVuEA7iJAFJzF7QuuHIcxzPV5VeFg==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", "dependencies": { - "js-yaml": "^4.0.0", - "remark-lint": "^8.0.0", - "remark-lint-blockquote-indentation": "^2.0.0", - "remark-lint-checkbox-character-style": "^3.0.0", - "remark-lint-checkbox-content-indent": "^3.0.0", - "remark-lint-code-block-style": "^2.0.0", - "remark-lint-definition-spacing": "^2.0.0", - "remark-lint-fenced-code-flag": "^2.0.0", - "remark-lint-fenced-code-marker": "^2.0.0", - "remark-lint-file-extension": "^1.0.3", - "remark-lint-final-definition": "^2.0.0", - "remark-lint-first-heading-level": "^2.0.0", - "remark-lint-heading-style": "^2.0.0", - "remark-lint-list-item-indent": "^2.0.0", - "remark-lint-maximum-line-length": "^2.0.0", - "remark-lint-no-consecutive-blank-lines": "^3.0.0", - "remark-lint-no-file-name-articles": "^1.0.4", - "remark-lint-no-file-name-consecutive-dashes": "^1.0.4", - "remark-lint-no-file-name-outer-dashes": "^1.0.5", - "remark-lint-no-heading-indent": "^3.0.0", - "remark-lint-no-multiple-toplevel-headings": "^2.0.0", - "remark-lint-no-shell-dollars": "^2.0.0", - "remark-lint-no-table-indentation": "^3.0.0", - "remark-lint-no-tabs": "^2.0.0", - "remark-lint-no-trailing-spaces": "^2.0.1", - "remark-lint-prohibited-strings": "^2.0.0", - "remark-lint-rule-style": "^2.0.0", - "remark-lint-strong-marker": "^2.0.0", - "remark-lint-table-cell-padding": "^3.0.0", - "remark-lint-table-pipes": "^3.0.0", - "remark-lint-unordered-list-marker-style": "^2.0.0", - "remark-preset-lint-recommended": "^5.0.0", - "semver": "^7.3.2", - "unified-lint-rule": "^1.0.6", - "unist-util-visit": "^2.0.3" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-preset-lint-node/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/remark-preset-lint-node/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "argparse": "^2.0.1" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-preset-lint-recommended": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-5.0.0.tgz", - "integrity": "sha512-uu+Ab8JCwMMaKvvB0LOWTWtM3uAvJbKQM/oyWCEJqj7lUVNTKZS575Ro5rKM3Dx7kQjjR1iw0e99bpAYTc5xNA==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", "dependencies": { - "remark-lint": "^8.0.0", - "remark-lint-final-newline": "^1.0.0", - "remark-lint-hard-break-spaces": "^2.0.0", - "remark-lint-list-item-bullet-indent": "^3.0.0", - "remark-lint-list-item-indent": "^2.0.0", - "remark-lint-no-auto-link-without-protocol": "^2.0.0", - "remark-lint-no-blockquote-without-marker": "^4.0.0", - "remark-lint-no-duplicate-definitions": "^2.0.0", - "remark-lint-no-heading-content-indent": "^3.0.0", - "remark-lint-no-inline-padding": "^3.0.0", - "remark-lint-no-literal-urls": "^2.0.0", - "remark-lint-no-shortcut-reference-image": "^2.0.0", - "remark-lint-no-shortcut-reference-link": "^2.0.0", - "remark-lint-no-undefined-references": "^3.0.0", - "remark-lint-no-unused-definitions": "^2.0.0", - "remark-lint-ordered-list-marker-style": "^2.0.0" + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-stringify": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", - "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "node_modules/remark-lint-checkbox-content-indent/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "mdast-util-to-markdown": "^0.6.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, + "node_modules/remark-lint-code-block-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.0.tgz", + "integrity": "sha512-xZMfFeaMOb5OIM4SrNz3QTRV3u5g3/+e6Oq40A3Apwd+a9Kx49lZbGxl8vfqaczP89PTNanm2e4OqqRsCen4Mg==", "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" + "node_modules/remark-lint-code-block-style/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/rollup": { - "version": "2.36.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.36.1.tgz", - "integrity": "sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, + "node_modules/remark-lint-code-block-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", "engines": { - "node": ">=10.0.0" + "node": ">=12" }, - "optionalDependencies": { - "fsevents": "~2.1.2" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "node_modules/remark-lint-code-block-style/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, + "node_modules/remark-lint-code-block-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/shx": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", - "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", - "dev": true, + "node_modules/remark-lint-code-block-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.4" - }, - "bin": { - "shx": "lib/cli.js" + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "node_modules/remark-lint-code-block-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" + "node_modules/remark-lint-code-block-style/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "node_modules/remark-lint-code-block-style/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "@types/unist": "^2.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "node_modules/remark-lint-code-block-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", "dependencies": { - "ansi-regex": "^5.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/remark-lint-code-block-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", "dependencies": { - "has-flag": "^4.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/remark-lint-code-block-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "is-number": "^7.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, - "engines": { - "node": ">=8.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/to-vfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz", - "integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==", + "node_modules/remark-lint-code-block-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "is-buffer": "^2.0.0", - "vfile": "^4.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "node_modules/remark-lint-definition-spacing": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.0.tgz", + "integrity": "sha512-3LxU7lwCpfPstldcGly2ULb8knH4IOqZHoABT2KyKFw3rRFUCAEUBSl0k5eetnXXNc/X4NlHmnyjIyzhyl4PhA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-definition-spacing/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "node_modules/remark-lint-definition-spacing/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "node_modules/remark-lint-definition-spacing/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-definition-spacing/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "bail": "^1.0.0", + "@types/unist": "^2.0.0", + "bail": "^2.0.0", "extend": "^3.0.0", "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unified-args": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-8.1.0.tgz", - "integrity": "sha512-t1HPS1cQPsVvt/6EtyWIbQGurza5684WGRigNghZRvzIdHm3LPgMdXPyGx0npORKzdiy5+urkF0rF5SXM8lBuQ==", + "node_modules/remark-lint-definition-spacing/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { - "camelcase": "^5.0.0", - "chalk": "^3.0.0", - "chokidar": "^3.0.0", - "fault": "^1.0.2", - "json5": "^2.0.0", - "minimist": "^1.2.0", - "text-table": "^0.2.0", - "unified-engine": "^8.0.0" + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unified-engine": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-8.0.0.tgz", - "integrity": "sha512-vLUezxCnjzz+ya4pYouRQVMT8k82Rk4fIj406UidRnSFJdGXFaQyQklAnalsQHJrLqAlaYPkXPUa1upfVSHGCA==", - "dependencies": { - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^1.0.0", - "figures": "^3.0.0", - "glob": "^7.0.3", - "ignore": "^5.0.0", - "is-buffer": "^2.0.0", - "is-empty": "^1.0.0", - "is-plain-obj": "^2.0.0", - "js-yaml": "^3.6.1", - "load-plugin": "^3.0.0", - "parse-json": "^5.0.0", - "to-vfile": "^6.0.0", - "trough": "^1.0.0", - "unist-util-inspect": "^5.0.0", - "vfile-reporter": "^6.0.0", - "vfile-statistics": "^1.1.0" - }, + "node_modules/remark-lint-definition-spacing/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unified-lint-rule": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.6.tgz", - "integrity": "sha512-YPK15YBFwnsVorDFG/u0cVVQN5G2a3V8zv5/N6KN3TCG+ajKtaALcy7u14DCSrJI+gZeyYquFL9cioJXOGXSvg==", - "dependencies": { - "wrapped": "^1.0.1" - }, + "node_modules/remark-lint-definition-spacing/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unified-message-control": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.2.tgz", - "integrity": "sha512-lhF8fKjDo2cIPx1re5X1QinqUonl+AN6F0XfEaab8w/hjqX7FZAhzu4P8g6pmYp09ld+HSWFwdRJj+Y8xD0q7Q==", + "node_modules/remark-lint-definition-spacing/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-generated": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", + "node_modules/remark-lint-definition-spacing/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-inspect": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-5.0.1.tgz", - "integrity": "sha512-fPNWewS593JSmg49HbnE86BJKuBi1/nMWhDSccBvbARfxezEuJV85EaARR9/VplveiwCoLm2kWq+DhP8TBaDpw==", + "node_modules/remark-lint-definition-spacing/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", "dependencies": { - "is-empty": "^1.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", - "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "node_modules/remark-lint-definition-spacing/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "node_modules/remark-lint-definition-spacing/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "node_modules/remark-lint-fenced-code-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.0.tgz", + "integrity": "sha512-wvyaTvQ5F78yuw4BDQsneTCvkxHGAjq0OuDQU4pawAZMYO3qFJlau7qoLppgquY1D+jBakejMT/yKnoQgRf1dQ==", "dependencies": { - "@types/unist": "^2.0.2" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "node_modules/remark-lint-fenced-code-flag/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-fenced-code-flag/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-fenced-code-flag/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-fenced-code-flag/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "node_modules/remark-lint-fenced-code-flag/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", "dependencies": { "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, + "node_modules/remark-lint-fenced-code-flag/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "node_modules/remark-lint-fenced-code-flag/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "node_modules/remark-lint-fenced-code-flag/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.2.tgz", - "integrity": "sha512-GN2bH2gs4eLnw/4jPSgfBjo+XCuvnX9elHICJZjVD4+NM0nsUrMTvdjGY5Sc/XG69XVTgLwj7hknQVc6M9FukA==", + "node_modules/remark-lint-fenced-code-flag/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", "dependencies": { - "repeat-string": "^1.5.0", - "string-width": "^4.0.0", - "supports-color": "^6.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-sort": "^2.1.2", - "vfile-statistics": "^1.1.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" + "node_modules/remark-lint-fenced-code-flag/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "node_modules/remark-lint-fenced-code-flag/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "has-flag": "^3.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, - "engines": { - "node": ">=6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-sort": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz", - "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==", + "node_modules/remark-lint-fenced-code-flag/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-statistics": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", - "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==", + "node_modules/remark-lint-fenced-code-marker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.0.tgz", + "integrity": "sha512-x3wr1+22Atr72Z7+dUS8cqwuz8m8d4UgCAfBTNO+E6pRLVeCnVMvEtuJbDI5UqBlqvkLGlNofV4lJZQvrZUxqQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/wrapped": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", - "integrity": "sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI=", - "dependencies": { - "co": "3.1.0", - "sliced": "^1.0.1" + "node_modules/remark-lint-fenced-code-marker/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/yallist": { + "node_modules/remark-lint-fenced-code-marker/node_modules/is-plain-obj": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "node_modules/remark-lint-fenced-code-marker/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, + "node_modules/remark-lint-fenced-code-marker/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@rollup/plugin-commonjs": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.0.0.tgz", - "integrity": "sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" + "node_modules/remark-lint-fenced-code-marker/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.0.8" + "node_modules/remark-lint-fenced-code-marker/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@rollup/plugin-node-resolve": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.0.1.tgz", - "integrity": "sha512-ltlsj/4Bhwwhb+Nb5xCz/6vieuEj2/BAkkqVIKmZwC7pIdl8srmgmglE4S0jFlZa32K4qvdQ6NHdmpRKD/LwoQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" + "node_modules/remark-lint-fenced-code-marker/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, + "node_modules/remark-lint-fenced-code-marker/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", "dependencies": { - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - } + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "@types/mdast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", - "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", - "requires": { - "@types/unist": "*" + "node_modules/remark-lint-fenced-code-marker/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@types/node": { - "version": "14.14.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", - "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", - "dev": true - }, - "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "requires": { - "@types/node": "*" + "node_modules/remark-lint-fenced-code-marker/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "node_modules/remark-lint-fenced-code-marker/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" + "node_modules/remark-lint-fenced-code-marker/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "node_modules/remark-lint-file-extension": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.0.tgz", + "integrity": "sha512-fZ0nDGyuZSgkrakLKl+cjqXwOT7iAz0wfSbrkCabYW3DdN6X1QYeSlMtHPizGXuri+AZhVkrUnujSn+9P4hJ2w==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" + "node_modules/remark-lint-file-extension/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/remark-lint-file-extension/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" + "node_modules/remark-lint-file-extension/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true + "node_modules/remark-lint-file-extension/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "node_modules/remark-lint-file-extension/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "chalk": { + "node_modules/remark-lint-file-extension/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "chokidar": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz", - "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, + "node_modules/remark-lint-file-extension/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", "dependencies": { - "fsevents": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", - "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", - "optional": true - } + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" + "node_modules/remark-lint-file-extension/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" + "node_modules/remark-lint-final-definition": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.0.tgz", + "integrity": "sha512-RHR8aku0jCH4AoHVepw9b0tCmiBevMtLPG1l5FKhbkLtBWk9GRRryuD3GExxsInEUN2P/a6FhvcBBtRSJbIfIA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "color-convert": { + "node_modules/remark-lint-final-definition/node_modules/bail": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "node_modules/remark-lint-final-definition/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "node_modules/remark-lint-final-definition/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "node_modules/remark-lint-final-definition/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "concat-stream": { + "node_modules/remark-lint-final-definition/node_modules/unified-lint-rule": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" + "node_modules/remark-lint-final-definition/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "node_modules/remark-lint-final-definition/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" + "node_modules/remark-lint-final-definition/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "escape-string-regexp": { + "node_modules/remark-lint-final-definition/node_modules/unist-util-visit": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "node_modules/remark-lint-final-definition/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "node_modules/remark-lint-final-definition/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "extend": { + "node_modules/remark-lint-final-definition/node_modules/vfile-message": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "requires": { - "format": "^0.2.0" + "node_modules/remark-lint-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.0.tgz", + "integrity": "sha512-3u1IbgVfUN5Qgid8iqc1qlZhzscs4YPu8mwyahvLWVKMkBtoRWjDIVL6+CXcPPoUB2k3p+zuZ5oaE4yfO5Pb4w==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" + "node_modules/remark-lint-final-newline/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" + "node_modules/remark-lint-final-newline/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" + "node_modules/remark-lint-final-newline/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" + "node_modules/remark-lint-final-newline/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "node_modules/remark-lint-final-newline/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true + "node_modules/remark-lint-final-newline/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "node_modules/remark-lint-final-newline/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "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" + "node_modules/remark-lint-final-newline/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" + "node_modules/remark-lint-first-heading-level": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.0.tgz", + "integrity": "sha512-SMvBHO4HJd1ZkFDfx7OikJAoq5FQe+nFPm3n4DeAKIgM1FywaC7tD7ShwTRUL2DJMzdPjlta7UQRtTryAQGj+w==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" + "node_modules/remark-lint-first-heading-level/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "has-flag": { + "node_modules/remark-lint-first-heading-level/node_modules/is-plain-obj": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "node_modules/remark-lint-first-heading-level/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/remark-lint-first-heading-level/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "node_modules/remark-lint-first-heading-level/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true + "node_modules/remark-lint-first-heading-level/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + "node_modules/remark-lint-first-heading-level/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "node_modules/remark-lint-first-heading-level/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" + "node_modules/remark-lint-first-heading-level/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "requires": { - "has": "^1.0.3" + "node_modules/remark-lint-first-heading-level/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "node_modules/remark-lint-first-heading-level/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "is-fullwidth-code-point": { + "node_modules/remark-lint-hard-break-spaces": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.0.tgz", + "integrity": "sha512-TNTI32Va6hE33pTYC6iqn4NvyZHqCULsOKKLnAzBocFFFIYuaNUdfKyVc9wknAAutbQLqApr8tgs1mLHtHm9Fw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" + "node_modules/remark-lint-hard-break-spaces/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "js-tokens": { + "node_modules/remark-lint-hard-break-spaces/node_modules/is-plain-obj": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "node_modules/remark-lint-hard-break-spaces/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "requires": { - "minimist": "^1.2.5" + "node_modules/remark-lint-hard-break-spaces/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "libnpmconfig": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", - "requires": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" + "node_modules/remark-lint-hard-break-spaces/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + "node_modules/remark-lint-hard-break-spaces/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "load-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-3.0.0.tgz", - "integrity": "sha512-od7eKCCZ62ITvFf8nHHrIiYmgOHb4xVNDRDqxBWSaao5FZyyZVX8OmRCbwjDGPrSrgIulwPNyBsWCGnhiDC0oQ==", - "requires": { - "libnpmconfig": "^1.0.0", - "resolve-from": "^5.0.0" + "node_modules/remark-lint-hard-break-spaces/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "locate-path": { + "node_modules/remark-lint-hard-break-spaces/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" + "node_modules/remark-lint-hard-break-spaces/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" + "node_modules/remark-lint-hard-break-spaces/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" + "node_modules/remark-lint-hard-break-spaces/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" + "node_modules/remark-lint-hard-break-spaces/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "requires": { - "repeat-string": "^1.0.0" + "node_modules/remark-lint-heading-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.0.tgz", + "integrity": "sha512-pPiXG24yXER7xXZr+J11iuMd1DXa71m6Cx7jqUO5z1Ptc7WkolcW6lNRFG76BCOJp8Jp6vH5eNITuQxYa0AnJw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-heading-style": "^2.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdast-comment-marker": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.1.2.tgz", - "integrity": "sha512-vTFXtmbbF3rgnTh3Zl3irso4LtvwUq/jaDvT2D1JqTGAwaipcS7RpTxzi6KjoRqI9n2yuAhzLDAC8xVTF3XYVQ==" - }, - "mdast-util-from-markdown": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz", - "integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "node_modules/remark-lint-heading-style/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "mdast-util-gfm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.1.tgz", - "integrity": "sha512-oE1W1zSXU2L2LHg91V22HC3Z1fbsOZTBYUQq+kpM29f9297TbRm0C1l3bQ88RREl0WaUQaB49G7trvwy5utUKQ==", - "requires": { - "mdast-util-gfm-autolink-literal": "^0.1.0", - "mdast-util-gfm-strikethrough": "^0.2.0", - "mdast-util-gfm-table": "^0.1.0", - "mdast-util-gfm-task-list-item": "^0.1.0", - "mdast-util-to-markdown": "^0.6.1" + "node_modules/remark-lint-heading-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "mdast-util-gfm-autolink-literal": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.2.tgz", - "integrity": "sha512-WFeIrcNNsfBety0gyWuiBIPing9UkVcl/m2iZOyW1uHEH2evjFocet2h77M24ub0WyZ4ucnQn/jWhO5Ozl6j4g==" + "node_modules/remark-lint-heading-style/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "mdast-util-gfm-strikethrough": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", - "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", - "requires": { - "mdast-util-to-markdown": "^0.6.0" + "node_modules/remark-lint-heading-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdast-util-gfm-table": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", - "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", - "requires": { - "markdown-table": "^2.0.0", - "mdast-util-to-markdown": "~0.6.0" + "node_modules/remark-lint-heading-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdast-util-gfm-task-list-item": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", - "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", - "requires": { - "mdast-util-to-markdown": "~0.6.0" + "node_modules/remark-lint-heading-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdast-util-heading-style": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", - "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==" + "node_modules/remark-lint-heading-style/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "mdast-util-to-markdown": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.2.tgz", - "integrity": "sha512-iRczns6WMvu0hUw02LXsPDJshBIwtUPbvHBWo19IQeU0YqmzlA8Pd30U8V7uiI0VPkxzS7A/NXBXH6u+HS87Zg==", - "requires": { + "node_modules/remark-lint-heading-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { "@types/unist": "^2.0.0", - "longest-streak": "^2.0.0", - "mdast-util-to-string": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.0.0", - "zwitch": "^1.0.0" + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" - }, - "micromark": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz", - "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==", - "requires": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" + "node_modules/remark-lint-heading-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.2.tgz", - "integrity": "sha512-ToQEpLkRgg7Tp8D3GM/SjZFPV0cCwWNxZmoEVIOQivOswRtPg7gg2WlCrtHhUWFNX+DgDjbq0iLOPGp4Y15oug==", - "requires": { - "micromark": "~2.11.0", - "micromark-extension-gfm-autolink-literal": "~0.5.0", - "micromark-extension-gfm-strikethrough": "~0.6.0", - "micromark-extension-gfm-table": "~0.4.0", - "micromark-extension-gfm-tagfilter": "~0.3.0", - "micromark-extension-gfm-task-list-item": "~0.3.0" + "node_modules/remark-lint-heading-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm-autolink-literal": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.4.tgz", - "integrity": "sha512-471VKd4k3SiX7vx9fC+IYeGQL0RnxwBBXeEc5WConb7naJDG5m16guA+VoFzyXchrvmU08t0dUWWPZ0mkJSXVw==", - "requires": { - "micromark": "~2.11.0" + "node_modules/remark-lint-heading-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm-strikethrough": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.3.tgz", - "integrity": "sha512-MKMoP9x2dsr1aeX46ibBwVf4Q6nJsi5aaUFTOMOID5VOLSxwl4CrqUV4OGFQd6AqhtzBJAxaV+N2trlTBtZDNQ==", - "requires": { - "micromark": "~2.11.0" + "node_modules/remark-lint-list-item-bullet-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.0.tgz", + "integrity": "sha512-b/U3wAJPE00xGQGYBvjPPsdXsBPJxUvITYgAZee7aA2sGEiflMGmg90anS2sJZEAoD4XtNzp96bPaY6QLN89dQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm-table": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.2.tgz", - "integrity": "sha512-AAzmj85XO1ydHYX0Lz52HGhcH2sZLm2AVvkwzELXWgZF6vGdq5yZ3CTByFRsqNUPyQBSIYFKLDAtc6KlnO42aw==", - "requires": { - "micromark": "~2.11.0" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "micromark-extension-gfm-tagfilter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", - "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "micromark-extension-gfm-task-list-item": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", - "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", - "requires": { - "micromark": "~2.11.0" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "normalize-path": { + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "node_modules/remark-lint-list-item-bullet-indent/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "path-exists": { + "node_modules/remark-lint-list-item-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.0.tgz", + "integrity": "sha512-z7doG/aJCy8ivmfbE/cSm9HOpIeUaV5zZHMqSsZ6XZ+wXIj4wtMFVhI7fsAVs5pAB1gzSvZQuwJOfSs2//Fw2g==", + "dependencies": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "node_modules/remark-lint-list-item-indent/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" + "node_modules/remark-lint-list-item-indent/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" + "node_modules/remark-lint-list-item-indent/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "remark": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", - "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", - "requires": { - "remark-parse": "^9.0.0", - "remark-stringify": "^9.0.0", - "unified": "^9.1.0" + "node_modules/remark-lint-list-item-indent/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-gfm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", - "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", - "requires": { - "mdast-util-gfm": "^0.1.0", - "micromark-extension-gfm": "^0.3.0" + "node_modules/remark-lint-list-item-indent/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-8.0.0.tgz", - "integrity": "sha512-ESI8qJQ/TIRjABDnqoFsTiZntu+FRifZ5fJ77yX63eIDijl/arvmDvT+tAf75/Nm5BFL4R2JFUtkHRGVjzYUsg==", - "requires": { - "remark-message-control": "^6.0.0" + "node_modules/remark-lint-list-item-indent/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-blockquote-indentation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-2.0.1.tgz", - "integrity": "sha512-uJ9az/Ms9AapnkWpLSCJfawBfnBI2Tn1yUsPNqIFv6YM98ymetItUMyP6ng9NFPqDvTQBbiarulkgoEo0wcafQ==", - "requires": { - "mdast-util-to-string": "^1.0.2", - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, - "dependencies": { - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" - } + "node_modules/remark-lint-list-item-indent/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-checkbox-character-style": { + "node_modules/remark-lint-list-item-indent/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-3.0.0.tgz", - "integrity": "sha512-691OJ5RdBRXVpvnOEiBhMB4uhHJSHVttw83O4qyAkNBiqxa1Axqhsz8FgmzYgRLQbOGd2ncVUcXG1LOJt6C0DQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-checkbox-content-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-3.0.0.tgz", - "integrity": "sha512-+T4+hoY85qZE2drD2rCe14vF7fAgD3Kv2fkFd1HRvv3M5Riy148w/4YeoBI5U5BpybGTVUeEUYLCeJ8zbJLjkw==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "node_modules/remark-lint-list-item-indent/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-code-block-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-2.0.1.tgz", - "integrity": "sha512-eRhmnColmSxJhO61GHZkvO67SpHDshVxs2j3+Zoc5Y1a4zQT2133ZAij04XKaBFfsVLjhbY/+YOWxgvtjx2nmA==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-list-item-indent/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-definition-spacing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-2.0.1.tgz", - "integrity": "sha512-xK9DOQO5MudITD189VyUiMHBIKltW1oc55L7Fti3i9DedXoBG7Phm+V9Mm7IdWzCVkquZVgVk63xQdqzSQRrSQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-list-item-indent/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-fenced-code-flag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-2.0.1.tgz", - "integrity": "sha512-+COnWHlS/h02FMxoZWxNlZW3Y8M0cQQpmx3aNCbG7xkyMyCKsMLg9EmRvYHHIbxQCuF3JT0WWx5AySqlc7d+NA==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-list-item-indent/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-fenced-code-marker": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-2.0.1.tgz", - "integrity": "sha512-lujpjm04enn3ma6lITlttadld6eQ1OWAEcT3qZzvFHp+zPraC0yr0eXlvtDN/0UH8mrln/QmGiZp3i8IdbucZg==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.0.tgz", + "integrity": "sha512-0x5TsUDlc4IDPUObNjVtcQxzI1JokUwbVpr22akWypnZaX9QMIL+Cp1OXrKRknZVU3rIndt4QCNnjMEYKezn1g==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-file-extension": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.5.tgz", - "integrity": "sha512-oVQdf5vEomwHkfQ7R/mgmsWW2H/t9kSvnrxtVoNOHr+qnOEafKKDn+AFhioN2kqtjCZBAjSSrePs6xGKmXKDTw==", - "requires": { - "unified-lint-rule": "^1.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "remark-lint-final-definition": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-2.1.0.tgz", - "integrity": "sha512-83K7n2icOHPfBzbR5Mr1o7cu8gOjD8FwJkFx/ly+rW+8SHfjCj4D3WOFGQ1xVdmHjfomBDXXDSNo2oiacADVXQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "remark-lint-final-newline": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.5.tgz", - "integrity": "sha512-rfLlW8+Fz2dqnaEgU4JwLA55CQF1T4mfSs/GwkkeUCGPenvEYwSkCN2KO2Gr1dy8qPoOdTFE1rSufLjmeTW5HA==", - "requires": { - "unified-lint-rule": "^1.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "remark-lint-first-heading-level": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-2.0.1.tgz", - "integrity": "sha512-XoK/eLfnz1VSA8QkfMbdbvlCqOwgw29MAWEGC4Cv0666nTcY9uWHlZ/SV/20YNmuEVdfCA+92v92mM486qcASQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-hard-break-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.1.tgz", - "integrity": "sha512-Qfn/BMQFamHhtbfLrL8Co/dbYJFLRL4PGVXZ5wumkUO5f9FkZC2RsV+MD9lisvGTkJK0ZEJrVVeaPbUIFM0OAw==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-heading-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-2.0.1.tgz", - "integrity": "sha512-IrFLNs0M5Vbn9qg51AYhGUfzgLAcDOjh2hFGMz3mx664dV6zLcNZOPSdJBBJq3JQR4gKpoXcNwN1+FFaIATj+A==", - "requires": { - "mdast-util-heading-style": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-list-item-bullet-indent": { + "node_modules/remark-lint-maximum-line-length/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-maximum-line-length/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-3.0.0.tgz", - "integrity": "sha512-X2rleWP8XReC4LXKF7Qi5vYiPJkA4Grx5zxsjHofFrVRz6j0PYOCuz7vsO+ZzMunFMfom6FODnscSWz4zouDVw==", - "requires": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-list-item-indent": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.1.tgz", - "integrity": "sha512-4IKbA9GA14Q9PzKSQI6KEHU/UGO36CSQEjaDIhmb9UOhyhuzz4vWhnSIsxyI73n9nl9GGRAMNUSGzr4pQUFwTA==", - "requires": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-maximum-line-length": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-2.0.3.tgz", - "integrity": "sha512-zyWHBFh1oPAy+gkaVFXiTHYP2WwriIeBtaarDqkweytw0+qmuikjVMJTWbQ3+XfYBreD7KKDM9SI79nkp0/IZQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-no-auto-link-without-protocol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.1.tgz", - "integrity": "sha512-TFcXxzucsfBb/5uMqGF1rQA+WJJqm1ZlYQXyvJEXigEZ8EAxsxZGPb/gOQARHl/y0vymAuYxMTaChavPKaBqpQ==", - "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-maximum-line-length/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-maximum-line-length/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", "dependencies": { - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" - } + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-no-blockquote-without-marker": { + "node_modules/remark-lint-no-auto-link-without-protocol": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.0.tgz", + "integrity": "sha512-qeJhWZcO0wnavTdpLU6M1q5RBfo4nZnYmzASoSCmIj/ZxIinluXLmLcMHC2Ol46egWdvwDNpr3V0dJP79fiJMQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/is-plain-obj": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-4.0.0.tgz", - "integrity": "sha512-Y59fMqdygRVFLk1gpx2Qhhaw5IKOR9T38Wf7pjR07bEFBGUNfcoNVIFMd1TCJfCPQxUyJzzSqfZz/KT7KdUuiQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "remark-lint-no-consecutive-blank-lines": { + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-3.0.0.tgz", - "integrity": "sha512-kmzLlOLrapBKEngwYFTdCZDmeOaze6adFPB7G0EdymD9V1mpAlnneINuOshRLEDKK5fAhXKiZXxdGIaMPkiXrA==", - "requires": { - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-no-duplicate-definitions": { + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-auto-link-without-protocol/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.0.tgz", + "integrity": "sha512-6m1KZE8X2OhNV9wpEPVUfFxdzgVD523unRkstlRedKC3ONLlqP/CIliAOITRmIGuUxXVjyD7mDC892bFJnJTfw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/bail": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.1.tgz", - "integrity": "sha512-XL22benJZB01m+aOse91nsu1IMFqeWJWme9QvoJuxIcBROO1BG1VoqLOkwNcawE/M/0CkvTo5rfx0eMlcnXOIw==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^2.0.0" + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "remark-lint-no-file-name-articles": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.5.tgz", - "integrity": "sha512-AQk5eTb3s3TAPPjiglZgqlQj4ycao+gPs8/XkdN1VCPUtewW0GgwoQe7YEuBKayJ6ioN8dGP37Kg/P/PlKaRQA==", - "requires": { - "unified-lint-rule": "^1.0.0" + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "remark-lint-no-file-name-consecutive-dashes": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.5.tgz", - "integrity": "sha512-Mg2IDsi790/dSdAzwnBnsMYdZm3qC2QgGwqOWcr0TPABJhhjC3p8r5fX4MNMTXI5It7B7bW9+ImmCeLOZiXkLg==", - "requires": { - "unified-lint-rule": "^1.0.0" + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "remark-lint-no-file-name-outer-dashes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.6.tgz", - "integrity": "sha512-rT8CmcIlenegS0Yst4maYXdZfqIjBOiRUY8j/KJkORF5tKH+3O1/S07025qPGmcRihzK3w4yO0K8rgkKQw0b9w==", - "requires": { - "unified-lint-rule": "^1.0.0" + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-no-heading-content-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-3.0.0.tgz", - "integrity": "sha512-yULDoVSIqKylLDfW6mVUbrHlyEWUSFtVFiKc+/BA412xDIhm8HZLUnP+FsuBC0OzbIZ+bO9Txy52WtO3LGnK1A==", - "requires": { - "mdast-util-heading-style": "^1.0.2", - "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "remark-lint-no-heading-indent": { + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unist-util-stringify-position": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-3.0.0.tgz", - "integrity": "sha512-b8ImhLv2AnRDxtYUODplzsl/7IwQ+lqRmD1bwbZgSerEP9MLaULW3SjH37EyA6z+8rCDjvEyppKKU6zec0TCjg==", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.0.tgz", + "integrity": "sha512-gP1b3lM+oemvA0WOC5HbvkjESG2BiZHL8ZDSX+wbg/2+7zu14rOmAAMiUOlk/CxbusttwJxsz8a/Wn1dEK/jPg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.0.tgz", + "integrity": "sha512-6VOGPegh2ZQ0d9yronmhNXhg2wLYA5litT7bC1ljg2LQwMTIjYOgJbJsQJSKWD+FiHuqVhdWvXHzyTbFCch8Aw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.0.tgz", + "integrity": "sha512-PgyJXEsZDT2r1bvtwaChwTjYKPxo47/OxpJmiozwLcnPsBNbsDtrH+W5gIjNkvkENNcIQD48WZ9jIwyJiskBng==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.0.tgz", + "integrity": "sha512-o7yz//+vel7IFDoZ/M0BmOS4sVE3sTAFOkeYlH44meGbNnEudr+TKKa0lwopMqZHKhXgUPSayCq+D5dgRO6JLA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.0.tgz", + "integrity": "sha512-SZS9FeGLty0wOBLTKyboDUZpjIKMihH88ZvgdqCUgIiDlZ9/72JKtZv43UuMnMVRgKJWQCRyZtT3nSNw3HwM+g==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.0.tgz", + "integrity": "sha512-2SljHUYTN83EN5DEZrl7WH4ibmUxai6gONhZaQrQOJyGUO2ReZj5Zdn4xi79NHpORSzCzjn2tSXPB6yL3AhJag==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-heading-style": "^2.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.0.tgz", + "integrity": "sha512-t4MWiMjPH6TOdM8d5i5Eik6NVrOokoYy6z0GnuI7PNrmNmVVIV9CVBJU94aSXZ7friKx5ucvUEw6NhXIRcNtOw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-indent/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.0.tgz", + "integrity": "sha512-dugEtHudM/UVQYzTbQoWy4aeG9Micd9g6O/uzN59sIMM8Xb+Srbv/p5/2JNtJWej9PmzINldE0AHjpuB8NiNLA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-inline-padding/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.0.tgz", + "integrity": "sha512-P+9VxemAeSGWGMmFGKcQMIsPgVDaoXnQLl0Bx/TuBms0Favb7XI3ecii/HjjDeks3zlrxlVhzvEkHBk1uH1tdA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.0.tgz", + "integrity": "sha512-HzPTSy9nu9RHSIUfZCbxEa7KP4CoKNbfI4SW8txh7KnYwr6vC6QgqXPF77z1sIpiSgD9X2z0LwMk0DBk1v3bmA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.0.tgz", + "integrity": "sha512-jygHSWi+w7C/VT6+oKIMHhrnMlURWF+ohjdtkxDc/C/7FXWyHg1nJR2t+c+j5Dmirz3oSfInSGw/jUfYP048GQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.0.tgz", + "integrity": "sha512-PyB5xkCd8moJf1MrmIXlBTSXZ8pkjXtdrmHzYba7La8S/6TKN2+LFrfN9daLG9pVsD0DSBAlvbajM/MBFh2DfQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.0.tgz", + "integrity": "sha512-SbPrP6ZfRA2IJ++L7xAivXl7PJdOMzBUlhVwlt5PsWJKWHX07TIB02GGAiMnSOLN0FnUCvgF2c5we6eU1K3plA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.0.tgz", + "integrity": "sha512-S1u4DHBS75xAcM/u1zsYize/0uB2u+xAoHbstN3JmFWsTRj5LUSppwkSrWsPk/3y9/jHJAQ4XSihwH7C95EObQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.0.tgz", + "integrity": "sha512-iK5gXQLoBchviHRNNDIWKQsMAbsLIZzK2ZKo0ywzNBHBckd8fy+wIP6RUosb6p/RBHtq1JG1lUC5ADg1PSj0tQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "vfile-location": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-tabs/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-trailing-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-trailing-spaces/-/remark-lint-no-trailing-spaces-2.0.1.tgz", + "integrity": "sha512-cj8t+nvtO6eAY2lJC7o5du8VeOCK13XiDUHL4U6k5aw6ZLr3EYWbQ/rNc6cr60eHkh5Ldm09KiZjV3CWpxqJ0g==", + "dependencies": { + "unified-lint-rule": "^1.0.2" + } + }, + "node_modules/remark-lint-no-undefined-references": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.0.tgz", + "integrity": "sha512-HI68vLoTTCXDADAp8LQ6RqCuf9QHX7bSaaqKI1V82EyvizxgnFtvN46XIi1uiDTN+Jv/KzAAGaFrofV8OJknBA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.0.tgz", + "integrity": "sha512-1LqEZx0IJx59ezXA9e0qq6h5W3n9I6oiBm3Kl+HvmXTFl1OME6f8SVFwtDbt9EaGmf+3NL+T24cWIhZWjmZ0bA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.0.tgz", + "integrity": "sha512-HDg5Fyg3tENtmI5SpEL34TvEjIiVX4GhuOjU8aOGF7T4SMG69kLyx+IWMKhg39pBw+3h4lG6FDC8IfqYXONNLg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-prohibited-strings": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-2.0.0.tgz", + "integrity": "sha512-N94RTdAT4qmYNBczNZEZbnpGvtl9GiLPO/xdG569IpbbtNFh5l+Nf5Mx5B1VeJMC8/hAR7wShag03Zf29MOO6Q==", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "unified-lint-rule": "^1.0.2", + "unist-util-position": "^3.1.0", + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.1" + } + }, + "node_modules/remark-lint-rule-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.0.tgz", + "integrity": "sha512-KHSPHW/7YCl9gHFsqqWOqIkJYmPuxTu/5G3Ks3lG8seBDf1bg+lPPUg5TigsKa/E7juVgfTR7AhK6P+lYAp4EA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-rule-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-rule-style/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.0.tgz", + "integrity": "sha512-nNyW3tKl0rEf2j784HzVWChAomCxzld+v2A5R5r5Zw5VogUNikZA7ZRwy51HsmhqiTWHArVGeyuvCPrpkTDZ0A==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.0.tgz", + "integrity": "sha512-jYBhfu/x0bEXt+wilHnm76q6wHnPVW2v2EuTdvAsxqkVtlvWSl9BbO4bb/L7jKqwlfiTK8E/luHKZuPiNWlucw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.0.tgz", + "integrity": "sha512-wOIAwkPAEDArKYMEpDylycGOCCt9hUxfgirgYCaHujCvyg484GWO+n+Moabgd19O9ZjuYr2P7akuOocsTh2z3g==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.0.tgz", + "integrity": "sha512-iwliMh7GzTdFAWKnVSabpdfcI6qoDE5PPX8hacDIZNbTe4xuUVFbopGCzsTlLiFQkTn6m3ePwOQn+lIbFofKDQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-unordered-list-marker-style/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "dependencies": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.0.tgz", + "integrity": "sha512-H1YwlVi/K0xmFT2JaVqnySNHdW/gqd9EQRbGVcH2mkxLNLdO+FIawkSU+UVYIhsm63pKAkHFW8HEtdoEAkNxOg==", + "dependencies": { + "js-yaml": "^4.0.0", + "remark-lint-blockquote-indentation": "^3.0.0", + "remark-lint-checkbox-character-style": "^4.0.0", + "remark-lint-checkbox-content-indent": "^4.0.0", + "remark-lint-code-block-style": "^3.0.0", + "remark-lint-definition-spacing": "^3.0.0", + "remark-lint-fenced-code-flag": "^3.0.0", + "remark-lint-fenced-code-marker": "^3.0.0", + "remark-lint-file-extension": "^2.0.0", + "remark-lint-final-definition": "^3.0.0", + "remark-lint-first-heading-level": "^3.0.0", + "remark-lint-heading-style": "^3.0.0", + "remark-lint-list-item-indent": "^3.0.0", + "remark-lint-maximum-line-length": "^3.0.0", + "remark-lint-no-consecutive-blank-lines": "^4.0.0", + "remark-lint-no-file-name-articles": "^2.0.0", + "remark-lint-no-file-name-consecutive-dashes": "^2.0.0", + "remark-lint-no-file-name-outer-dashes": "^2.0.0", + "remark-lint-no-heading-indent": "^4.0.0", + "remark-lint-no-multiple-toplevel-headings": "^3.0.0", + "remark-lint-no-shell-dollars": "^3.0.0", + "remark-lint-no-table-indentation": "^4.0.0", + "remark-lint-no-tabs": "^3.0.0", + "remark-lint-no-trailing-spaces": "^2.0.1", + "remark-lint-prohibited-strings": "^2.0.0", + "remark-lint-rule-style": "^3.0.0", + "remark-lint-strong-marker": "^3.0.0", + "remark-lint-table-cell-padding": "^4.0.0", + "remark-lint-table-pipes": "^4.0.0", + "remark-lint-unordered-list-marker-style": "^3.0.0", + "remark-preset-lint-recommended": "^6.0.0", + "semver": "^7.3.2", + "unified-lint-rule": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/remark-preset-lint-node/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/remark-preset-lint-node/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-preset-lint-node/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-preset-lint-node/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/remark-preset-lint-node/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "dependencies": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-node/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.0.tgz", + "integrity": "sha512-ZVugDvBLFQ2JZ/tRIb0q/Oo4Qwp8s8AD8M/8GU7VgQYQ39GDVzo8lUTg2ugWy3YuBCX7wmnP0UDOSwIJt7vn0A==", + "dependencies": { + "@types/mdast": "^3.0.0", + "remark-lint": "^9.0.0", + "remark-lint-final-newline": "^2.0.0", + "remark-lint-hard-break-spaces": "^3.0.0", + "remark-lint-list-item-bullet-indent": "^4.0.0", + "remark-lint-list-item-indent": "^3.0.0", + "remark-lint-no-auto-link-without-protocol": "^3.0.0", + "remark-lint-no-blockquote-without-marker": "^5.0.0", + "remark-lint-no-duplicate-definitions": "^3.0.0", + "remark-lint-no-heading-content-indent": "^4.0.0", + "remark-lint-no-inline-padding": "^4.0.0", + "remark-lint-no-literal-urls": "^3.0.0", + "remark-lint-no-shortcut-reference-image": "^3.0.0", + "remark-lint-no-shortcut-reference-link": "^3.0.0", + "remark-lint-no-undefined-references": "^4.0.0", + "remark-lint-no-unused-definitions": "^3.0.0", + "remark-lint-ordered-list-marker-style": "^3.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/mdast-comment-marker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-2.0.0.tgz", + "integrity": "sha512-LQ4sf7vUzxz4mQQlzzBDgjaCJO5A0lkIAT9TyeNMfqaP31ooP1Qw9hprf7/V3NCo5FA1nvo5gbnfLVRY79QlDQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/remark-lint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.0.tgz", + "integrity": "sha512-ETO4zI48PR1Nz42YiyaYBzyhOiEfppXLnck7HW2pjKqxd36SIyQgM6sxD4ToMQI9KuCgy8mLAl/iVJoDLKxVjw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "remark-message-control": "^7.0.0", + "unified": "^10.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/remark-message-control": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-7.0.0.tgz", + "integrity": "sha512-KZySoC97TrMPYfIZ9vJ7wxvQwniy68K6WCY3vmSedDN5YuGfdVOpMj6sjaZQcqbWZV9n7BhrT70E3xaUTtk4hA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-comment-marker": "^2.0.0", + "rehype": "^12.0.0", + "unified": "^10.0.0", + "unified-message-control": "^4.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unified-message-control": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-4.0.0.tgz", + "integrity": "sha512-1b92N+VkPHftOsvXNOtkJm4wHlr+UDmTBF2dUzepn40oy9NxanJ9xS1RwUBTjXJwqr2K0kMbEyv1Krdsho7+Iw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^3.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unist-util-visit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", + "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/unist-util-visit-parents": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", + "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended/node_modules/vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup": { + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.36.1.tgz", + "integrity": "sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", + "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.3", + "shelljs": "^0.8.4" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/space-separated-tokens": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", + "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.1.tgz", + "integrity": "sha512-gmMQxKXPWIO3NXNSPyWNhlYcBNGpPA/487D+9dLPnU4xBnIrnHdr8cv5rGJOS/1BRxEXRb7uKwg7BA36IWV7xg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities/node_modules/character-entities-legacy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz", + "integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-vfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz", + "integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==", + "dependencies": { + "is-buffer": "^2.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/unified": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-args": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-8.1.0.tgz", + "integrity": "sha512-t1HPS1cQPsVvt/6EtyWIbQGurza5684WGRigNghZRvzIdHm3LPgMdXPyGx0npORKzdiy5+urkF0rF5SXM8lBuQ==", + "dependencies": { + "camelcase": "^5.0.0", + "chalk": "^3.0.0", + "chokidar": "^3.0.0", + "fault": "^1.0.2", + "json5": "^2.0.0", + "minimist": "^1.2.0", + "text-table": "^0.2.0", + "unified-engine": "^8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-8.0.0.tgz", + "integrity": "sha512-vLUezxCnjzz+ya4pYouRQVMT8k82Rk4fIj406UidRnSFJdGXFaQyQklAnalsQHJrLqAlaYPkXPUa1upfVSHGCA==", + "dependencies": { + "concat-stream": "^2.0.0", + "debug": "^4.0.0", + "fault": "^1.0.0", + "figures": "^3.0.0", + "glob": "^7.0.3", + "ignore": "^5.0.0", + "is-buffer": "^2.0.0", + "is-empty": "^1.0.0", + "is-plain-obj": "^2.0.0", + "js-yaml": "^3.6.1", + "load-plugin": "^3.0.0", + "parse-json": "^5.0.0", + "to-vfile": "^6.0.0", + "trough": "^1.0.0", + "unist-util-inspect": "^5.0.0", + "vfile-reporter": "^6.0.0", + "vfile-statistics": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-lint-rule": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.6.tgz", + "integrity": "sha512-YPK15YBFwnsVorDFG/u0cVVQN5G2a3V8zv5/N6KN3TCG+ajKtaALcy7u14DCSrJI+gZeyYquFL9cioJXOGXSvg==", + "dependencies": { + "wrapped": "^1.0.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-message-control": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.2.tgz", + "integrity": "sha512-lhF8fKjDo2cIPx1re5X1QinqUonl+AN6F0XfEaab8w/hjqX7FZAhzu4P8g6pmYp09ld+HSWFwdRJj+Y8xD0q7Q==", + "dependencies": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-generated": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", + "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-inspect": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-5.0.1.tgz", + "integrity": "sha512-fPNWewS593JSmg49HbnE86BJKuBi1/nMWhDSccBvbARfxezEuJV85EaARR9/VplveiwCoLm2kWq+DhP8TBaDpw==", + "dependencies": { + "is-empty": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-6.0.2.tgz", + "integrity": "sha512-GN2bH2gs4eLnw/4jPSgfBjo+XCuvnX9elHICJZjVD4+NM0nsUrMTvdjGY5Sc/XG69XVTgLwj7hknQVc6M9FukA==", + "dependencies": { + "repeat-string": "^1.5.0", + "string-width": "^4.0.0", + "supports-color": "^6.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-sort": "^2.1.2", + "vfile-statistics": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/vfile-reporter/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vfile-sort": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz", + "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-statistics": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", + "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.0.tgz", + "integrity": "sha512-dE7ELZRVWh0ceQsRgkjLgsAvwTuv3kcjSY/hLjqL0llleUlQBDjE9JkB9FCBY5F2mnFEwiyJoowl8+NVGHe8dw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/wrapped": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", + "integrity": "sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI=", + "dependencies": { + "co": "3.1.0", + "sliced": "^1.0.1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@rollup/plugin-commonjs": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.0.0.tgz", + "integrity": "sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.0.1.tgz", + "integrity": "sha512-ltlsj/4Bhwwhb+Nb5xCz/6vieuEj2/BAkkqVIKmZwC7pIdl8srmgmglE4S0jFlZa32K4qvdQ6NHdmpRKD/LwoQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/hast": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.2.tgz", + "integrity": "sha512-Op5W7jYgZI7AWKY5wQ0/QNMzQM7dGQPyW1rXKNiymVCy5iTfdPuGu4HhYNOM2sIv8gUfIuIdcYlXmAepwaowow==", + "requires": { + "@types/unist": "*" + } + }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "requires": { + "@types/unist": "*" + } + }, + "@types/node": { + "version": "14.14.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", + "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", + "dev": true + }, + "@types/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==" + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "ccount": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", + "integrity": "sha512-VOR0NWFYX65n9gELQdcpqsie5L5ihBXuZGAgaPEp/U7IOSjnPMEH6geE+2f6lcekaNEfWzAHS45mPvSo5bqsUA==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities-html4": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.0.0.tgz", + "integrity": "sha512-dwT2xh5ZhUAjyP96k57ilMKoTQyASaw9IAMR9U5c1lCu2RUni6O6jxfpUEdO2RcPT6TJFvr8pqsbami4Jk+2oA==" + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, + "chokidar": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz", + "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "dependencies": { + "fsevents": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", + "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", + "optional": true + } + } + }, + "co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "comma-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", + "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "requires": { + "format": "^0.2.0" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "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-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hast-util-from-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.0.tgz", + "integrity": "sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==", + "requires": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "dependencies": { + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "hast-util-is-element": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.1.tgz", + "integrity": "sha512-ag0fiZfRWsPiR1udvnSbaazJLGv8qd8E+/e3rW8rUZhbKG4HNJmFL4QkEceN+22BgE+uozXY30z/s+2dL6Z++g==", + "requires": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" + } + }, + "hast-util-parse-selector": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz", + "integrity": "sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==", + "requires": { + "@types/hast": "^2.0.0" + } + }, + "hast-util-to-html": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.1.tgz", + "integrity": "sha512-S1mTqXvWVGIxrWw0xOHHvmevwCBFTRGNvXWsjE32IyEAlMhbMkK+ZuP6CAqkQ6Vb7swrehaHpfXHEI6voGDh0w==", + "requires": { + "@types/hast": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "unist-util-is": "^5.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + } + } + }, + "hast-util-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", + "integrity": "sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==" + }, + "hastscript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", + "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + } + }, + "html-void-elements": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", + "integrity": "sha512-4OYzQQsBt0G9bJ/nM9/DDsjm4+fVdzAaPJJcWk5QwA3GIAPxQEeOR0rsI8HbDHQz5Gta8pVvGnnTNSbZVEVvkQ==" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, + "is-empty": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", + "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "libnpmconfig": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", + "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "load-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-3.0.0.tgz", + "integrity": "sha512-od7eKCCZ62ITvFf8nHHrIiYmgOHb4xVNDRDqxBWSaao5FZyyZVX8OmRCbwjDGPrSrgIulwPNyBsWCGnhiDC0oQ==", + "requires": { + "libnpmconfig": "^1.0.0", + "resolve-from": "^5.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "markdown-extensions": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", + "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" + }, + "markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "requires": { + "repeat-string": "^1.0.0" + } + }, + "mdast-comment-marker": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.1.2.tgz", + "integrity": "sha512-vTFXtmbbF3rgnTh3Zl3irso4LtvwUq/jaDvT2D1JqTGAwaipcS7RpTxzi6KjoRqI9n2yuAhzLDAC8xVTF3XYVQ==" + }, + "mdast-util-from-markdown": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz", + "integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "mdast-util-gfm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.1.tgz", + "integrity": "sha512-oE1W1zSXU2L2LHg91V22HC3Z1fbsOZTBYUQq+kpM29f9297TbRm0C1l3bQ88RREl0WaUQaB49G7trvwy5utUKQ==", + "requires": { + "mdast-util-gfm-autolink-literal": "^0.1.0", + "mdast-util-gfm-strikethrough": "^0.2.0", + "mdast-util-gfm-table": "^0.1.0", + "mdast-util-gfm-task-list-item": "^0.1.0", + "mdast-util-to-markdown": "^0.6.1" + } + }, + "mdast-util-gfm-autolink-literal": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.2.tgz", + "integrity": "sha512-WFeIrcNNsfBety0gyWuiBIPing9UkVcl/m2iZOyW1uHEH2evjFocet2h77M24ub0WyZ4ucnQn/jWhO5Ozl6j4g==" + }, + "mdast-util-gfm-strikethrough": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "requires": { + "mdast-util-to-markdown": "^0.6.0" + } + }, + "mdast-util-gfm-table": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "requires": { + "markdown-table": "^2.0.0", + "mdast-util-to-markdown": "~0.6.0" + } + }, + "mdast-util-gfm-task-list-item": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "requires": { + "mdast-util-to-markdown": "~0.6.0" + } + }, + "mdast-util-heading-style": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-2.0.0.tgz", + "integrity": "sha512-q9+WW2hJduW51LgV2r/fcU5wIt2GLFf0yYHxyi0f2aaxnC63ErBSOAJlhP6nbQ6yeG5rTCozbwOi4QNDPKV0zw==", + "requires": { + "@types/mdast": "^3.0.0" + } + }, + "mdast-util-to-markdown": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.2.tgz", + "integrity": "sha512-iRczns6WMvu0hUw02LXsPDJshBIwtUPbvHBWo19IQeU0YqmzlA8Pd30U8V7uiI0VPkxzS7A/NXBXH6u+HS87Zg==", + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" + }, + "micromark": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz", + "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==", + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "micromark-extension-gfm": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.2.tgz", + "integrity": "sha512-ToQEpLkRgg7Tp8D3GM/SjZFPV0cCwWNxZmoEVIOQivOswRtPg7gg2WlCrtHhUWFNX+DgDjbq0iLOPGp4Y15oug==", + "requires": { + "micromark": "~2.11.0", + "micromark-extension-gfm-autolink-literal": "~0.5.0", + "micromark-extension-gfm-strikethrough": "~0.6.0", + "micromark-extension-gfm-table": "~0.4.0", + "micromark-extension-gfm-tagfilter": "~0.3.0", + "micromark-extension-gfm-task-list-item": "~0.3.0" + } + }, + "micromark-extension-gfm-autolink-literal": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.4.tgz", + "integrity": "sha512-471VKd4k3SiX7vx9fC+IYeGQL0RnxwBBXeEc5WConb7naJDG5m16guA+VoFzyXchrvmU08t0dUWWPZ0mkJSXVw==", + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-gfm-strikethrough": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.3.tgz", + "integrity": "sha512-MKMoP9x2dsr1aeX46ibBwVf4Q6nJsi5aaUFTOMOID5VOLSxwl4CrqUV4OGFQd6AqhtzBJAxaV+N2trlTBtZDNQ==", + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-gfm-table": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.2.tgz", + "integrity": "sha512-AAzmj85XO1ydHYX0Lz52HGhcH2sZLm2AVvkwzELXWgZF6vGdq5yZ3CTByFRsqNUPyQBSIYFKLDAtc6KlnO42aw==", + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-extension-gfm-tagfilter": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" + }, + "micromark-extension-gfm-task-list-item": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "requires": { + "micromark": "~2.11.0" + } + }, + "micromark-util-normalize-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", + "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-symbol": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.0.tgz", + "integrity": "sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" + }, + "property-information": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.0.1.tgz", + "integrity": "sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "rehype": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", + "integrity": "sha512-gZcttmf9R5IYHb8AlI1rlmWqXS1yX0rSB/S5ZGJs8atfYZy2DobvH3Ic/gSzB+HL/+oOHPtBguw1TprfhxXBgQ==", + "requires": { + "@types/hast": "^2.0.0", + "rehype-parse": "^8.0.0", + "rehype-stringify": "^9.0.0", + "unified": "^10.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "rehype-parse": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.2.tgz", + "integrity": "sha512-Y5AvUbTareuAcCQITTbC9SGagm1IvOOSfG5CTTaOUW0pEeoNHkOq4YmMaEywUmSwwOgel3gOF3O7Mwl1acoBzg==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "rehype-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.1.tgz", + "integrity": "sha512-xfhm8Erp7yL+RRgYmtZMJUqu6OSguwOQMfR2LkqT1dgNDQheClFMaDPVERy4/su7o0eHo0PKFGn4L68kOjVdRQ==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-to-html": "^8.0.0", + "unified": "^10.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "requires": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + } + }, + "remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "requires": { + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" + } + }, + "remark-lint": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-8.0.0.tgz", + "integrity": "sha512-ESI8qJQ/TIRjABDnqoFsTiZntu+FRifZ5fJ77yX63eIDijl/arvmDvT+tAf75/Nm5BFL4R2JFUtkHRGVjzYUsg==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-lint-blockquote-indentation": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.0.tgz", + "integrity": "sha512-qWWyAJWHwnVFsfKEyl51os1rr4ex9KX398g8326esJ2/RFsCYJbJaXmVk/S+uf7B7HfOWFuJo+tu/7jlZZ54+Q==", + "requires": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-checkbox-character-style": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.0.tgz", + "integrity": "sha512-NHpVZOcTJeLOI1gGOvVDz8i3sXVY3s9K+OADupEA89Syfs4YAbnrij8OMJ6ozbHTn4av/HyVfsF4IK8X2pBUeQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-checkbox-content-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.0.tgz", + "integrity": "sha512-WeB8aSC1oesu0t/wcqNEbn3bg0kRw+NK7Y5xrhQsREw6NcH1TnvjH95PvizFT5LxXAGhz4AtCFz0B28YugSznQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-code-block-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.0.tgz", + "integrity": "sha512-xZMfFeaMOb5OIM4SrNz3QTRV3u5g3/+e6Oq40A3Apwd+a9Kx49lZbGxl8vfqaczP89PTNanm2e4OqqRsCen4Mg==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-definition-spacing": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.0.tgz", + "integrity": "sha512-3LxU7lwCpfPstldcGly2ULb8knH4IOqZHoABT2KyKFw3rRFUCAEUBSl0k5eetnXXNc/X4NlHmnyjIyzhyl4PhA==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-fenced-code-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.0.tgz", + "integrity": "sha512-wvyaTvQ5F78yuw4BDQsneTCvkxHGAjq0OuDQU4pawAZMYO3qFJlau7qoLppgquY1D+jBakejMT/yKnoQgRf1dQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-fenced-code-marker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.0.tgz", + "integrity": "sha512-x3wr1+22Atr72Z7+dUS8cqwuz8m8d4UgCAfBTNO+E6pRLVeCnVMvEtuJbDI5UqBlqvkLGlNofV4lJZQvrZUxqQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-file-extension": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.0.tgz", + "integrity": "sha512-fZ0nDGyuZSgkrakLKl+cjqXwOT7iAz0wfSbrkCabYW3DdN6X1QYeSlMtHPizGXuri+AZhVkrUnujSn+9P4hJ2w==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-final-definition": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.0.tgz", + "integrity": "sha512-RHR8aku0jCH4AoHVepw9b0tCmiBevMtLPG1l5FKhbkLtBWk9GRRryuD3GExxsInEUN2P/a6FhvcBBtRSJbIfIA==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.0.tgz", + "integrity": "sha512-3u1IbgVfUN5Qgid8iqc1qlZhzscs4YPu8mwyahvLWVKMkBtoRWjDIVL6+CXcPPoUB2k3p+zuZ5oaE4yfO5Pb4w==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-first-heading-level": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.0.tgz", + "integrity": "sha512-SMvBHO4HJd1ZkFDfx7OikJAoq5FQe+nFPm3n4DeAKIgM1FywaC7tD7ShwTRUL2DJMzdPjlta7UQRtTryAQGj+w==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-hard-break-spaces": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.0.tgz", + "integrity": "sha512-TNTI32Va6hE33pTYC6iqn4NvyZHqCULsOKKLnAzBocFFFIYuaNUdfKyVc9wknAAutbQLqApr8tgs1mLHtHm9Fw==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-heading-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.0.tgz", + "integrity": "sha512-pPiXG24yXER7xXZr+J11iuMd1DXa71m6Cx7jqUO5z1Ptc7WkolcW6lNRFG76BCOJp8Jp6vH5eNITuQxYa0AnJw==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-heading-style": "^2.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-list-item-bullet-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.0.tgz", + "integrity": "sha512-b/U3wAJPE00xGQGYBvjPPsdXsBPJxUvITYgAZee7aA2sGEiflMGmg90anS2sJZEAoD4XtNzp96bPaY6QLN89dQ==", + "requires": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-list-item-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.0.tgz", + "integrity": "sha512-z7doG/aJCy8ivmfbE/cSm9HOpIeUaV5zZHMqSsZ6XZ+wXIj4wtMFVhI7fsAVs5pAB1gzSvZQuwJOfSs2//Fw2g==", + "requires": { + "@types/mdast": "^3.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-maximum-line-length": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.0.tgz", + "integrity": "sha512-0x5TsUDlc4IDPUObNjVtcQxzI1JokUwbVpr22akWypnZaX9QMIL+Cp1OXrKRknZVU3rIndt4QCNnjMEYKezn1g==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-auto-link-without-protocol": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.0.tgz", + "integrity": "sha512-qeJhWZcO0wnavTdpLU6M1q5RBfo4nZnYmzASoSCmIj/ZxIinluXLmLcMHC2Ol46egWdvwDNpr3V0dJP79fiJMQ==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-blockquote-without-marker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.0.tgz", + "integrity": "sha512-6m1KZE8X2OhNV9wpEPVUfFxdzgVD523unRkstlRedKC3ONLlqP/CIliAOITRmIGuUxXVjyD7mDC892bFJnJTfw==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-consecutive-blank-lines": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.0.tgz", + "integrity": "sha512-gP1b3lM+oemvA0WOC5HbvkjESG2BiZHL8ZDSX+wbg/2+7zu14rOmAAMiUOlk/CxbusttwJxsz8a/Wn1dEK/jPg==", + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-duplicate-definitions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.0.tgz", + "integrity": "sha512-6VOGPegh2ZQ0d9yronmhNXhg2wLYA5litT7bC1ljg2LQwMTIjYOgJbJsQJSKWD+FiHuqVhdWvXHzyTbFCch8Aw==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-file-name-articles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.0.tgz", + "integrity": "sha512-PgyJXEsZDT2r1bvtwaChwTjYKPxo47/OxpJmiozwLcnPsBNbsDtrH+W5gIjNkvkENNcIQD48WZ9jIwyJiskBng==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-file-name-consecutive-dashes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.0.tgz", + "integrity": "sha512-o7yz//+vel7IFDoZ/M0BmOS4sVE3sTAFOkeYlH44meGbNnEudr+TKKa0lwopMqZHKhXgUPSayCq+D5dgRO6JLA==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-file-name-outer-dashes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.0.tgz", + "integrity": "sha512-SZS9FeGLty0wOBLTKyboDUZpjIKMihH88ZvgdqCUgIiDlZ9/72JKtZv43UuMnMVRgKJWQCRyZtT3nSNw3HwM+g==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-heading-content-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.0.tgz", + "integrity": "sha512-2SljHUYTN83EN5DEZrl7WH4ibmUxai6gONhZaQrQOJyGUO2ReZj5Zdn4xi79NHpORSzCzjn2tSXPB6yL3AhJag==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-heading-style": "^2.0.0", + "pluralize": "^8.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-heading-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.0.tgz", + "integrity": "sha512-t4MWiMjPH6TOdM8d5i5Eik6NVrOokoYy6z0GnuI7PNrmNmVVIV9CVBJU94aSXZ7friKx5ucvUEw6NhXIRcNtOw==", "requires": { + "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-inline-padding": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.0.tgz", + "integrity": "sha512-dugEtHudM/UVQYzTbQoWy4aeG9Micd9g6O/uzN59sIMM8Xb+Srbv/p5/2JNtJWej9PmzINldE0AHjpuB8NiNLA==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-literal-urls": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.0.tgz", + "integrity": "sha512-P+9VxemAeSGWGMmFGKcQMIsPgVDaoXnQLl0Bx/TuBms0Favb7XI3ecii/HjjDeks3zlrxlVhzvEkHBk1uH1tdA==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-multiple-toplevel-headings": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.0.tgz", + "integrity": "sha512-HzPTSy9nu9RHSIUfZCbxEa7KP4CoKNbfI4SW8txh7KnYwr6vC6QgqXPF77z1sIpiSgD9X2z0LwMk0DBk1v3bmA==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-shell-dollars": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.0.tgz", + "integrity": "sha512-jygHSWi+w7C/VT6+oKIMHhrnMlURWF+ohjdtkxDc/C/7FXWyHg1nJR2t+c+j5Dmirz3oSfInSGw/jUfYP048GQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } + } + }, + "remark-lint-no-shortcut-reference-image": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.0.tgz", + "integrity": "sha512-PyB5xkCd8moJf1MrmIXlBTSXZ8pkjXtdrmHzYba7La8S/6TKN2+LFrfN9daLG9pVsD0DSBAlvbajM/MBFh2DfQ==", + "requires": { + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, - "remark-lint-no-inline-padding": { + "remark-lint-no-shortcut-reference-link": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-3.0.0.tgz", - "integrity": "sha512-3s9uW3Yux9RFC0xV81MQX3bsYs+UY7nPnRuMxeIxgcVwxQ4E/mTJd9QjXUwBhU9kdPtJ5AalngdmOW2Tgar8Cg==", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.0.tgz", + "integrity": "sha512-SbPrP6ZfRA2IJ++L7xAivXl7PJdOMzBUlhVwlt5PsWJKWHX07TIB02GGAiMnSOLN0FnUCvgF2c5we6eU1K3plA==", "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" }, "dependencies": { - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } } } }, - "remark-lint-no-literal-urls": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.1.tgz", - "integrity": "sha512-IDdKtWOMuKVQIlb1CnsgBoyoTcXU3LppelDFAIZePbRPySVHklTtuK57kacgU5grc7gPM04bZV96eliGrRU7Iw==", + "remark-lint-no-table-indentation": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.0.tgz", + "integrity": "sha512-S1u4DHBS75xAcM/u1zsYize/0uB2u+xAoHbstN3JmFWsTRj5LUSppwkSrWsPk/3y9/jHJAQ4XSihwH7C95EObQ==", "requires": { - "mdast-util-to-string": "^1.0.2", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" }, "dependencies": { - "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } } } }, - "remark-lint-no-multiple-toplevel-headings": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-2.0.1.tgz", - "integrity": "sha512-VKSItR6c+u3OsE5pUiSmNusERNyQS9Nnji26ezoQ1uvy06k3RypIjmzQqJ/hCkSiF+hoyC3ibtrrGT8gorzCmQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^2.0.0" - } - }, - "remark-lint-no-shell-dollars": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-2.0.2.tgz", - "integrity": "sha512-zhkHZOuyaD3r/TUUkkVqW0OxsR9fnSrAnHIF63nfJoAAUezPOu8D1NBsni6rX8H2DqGbPYkoeWrNsTwiKP0yow==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" - } - }, - "remark-lint-no-shortcut-reference-image": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.1.tgz", - "integrity": "sha512-2jcZBdnN6ecP7u87gkOVFrvICLXIU5OsdWbo160FvS/2v3qqqwF2e/n/e7D9Jd+KTq1mR1gEVVuTqkWWuh3cig==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" - } - }, - "remark-lint-no-shortcut-reference-link": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.1.tgz", - "integrity": "sha512-pTZbslG412rrwwGQkIboA8wpBvcjmGFmvugIA+UQR+GfFysKtJ5OZMPGJ98/9CYWjw9Z5m0/EktplZ5TjFjqwA==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" - } - }, - "remark-lint-no-table-indentation": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-3.0.0.tgz", - "integrity": "sha512-+l7GovI6T+3LhnTtz/SmSRyOb6Fxy6tmaObKHrwb/GAebI/4MhFS1LVo3vbiP/RpPYtyQoFbbuXI55hqBG4ibQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.0.0" - } - }, "remark-lint-no-tabs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-2.0.1.tgz", - "integrity": "sha512-Fy5fMKNA8AsfhRtxyxBnHlGMpDDfns9VSSYv00RiC96qwRD82VhDRM3tYWZRBBxE+j71t6g47x9o/poGC7PThQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.0.tgz", + "integrity": "sha512-iK5gXQLoBchviHRNNDIWKQsMAbsLIZzK2ZKo0ywzNBHBckd8fy+wIP6RUosb6p/RBHtq1JG1lUC5ADg1PSj0tQ==", "requires": { - "unified-lint-rule": "^1.0.0", - "vfile-location": "^3.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "vfile-location": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-no-trailing-spaces": { @@ -4110,37 +14365,344 @@ } }, "remark-lint-no-undefined-references": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-3.0.0.tgz", - "integrity": "sha512-0hzaJS9GuzSQVOeeNdJr/s66LRQOzp618xuOQPYWHcJdd+SCaRTyWbjMrTM/cCI5L1sYjgurp410NkIBQ32Vqg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.0.tgz", + "integrity": "sha512-HI68vLoTTCXDADAp8LQ6RqCuf9QHX7bSaaqKI1V82EyvizxgnFtvN46XIi1uiDTN+Jv/KzAAGaFrofV8OJknBA==", "requires": { - "collapse-white-space": "^1.0.4", - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.1.0", - "unist-util-visit": "^2.0.0", - "vfile-location": "^3.1.0" + "@types/mdast": "^3.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile-location": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-no-unused-definitions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.1.tgz", - "integrity": "sha512-+BMc0BOjc364SvKYLkspmxDch8OaKPbnUGgQBvK0Bmlwy42baR4C9zhwAWBxm0SBy5Z4AyM4G4jKpLXPH40Oxg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.0.tgz", + "integrity": "sha512-1LqEZx0IJx59ezXA9e0qq6h5W3n9I6oiBm3Kl+HvmXTFl1OME6f8SVFwtDbt9EaGmf+3NL+T24cWIhZWjmZ0bA==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-ordered-list-marker-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.1.tgz", - "integrity": "sha512-Cnpw1Dn9CHn+wBjlyf4qhPciiJroFOEGmyfX008sQ8uGoPZsoBVIJx76usnHklojSONbpjEDcJCjnOvfAcWW1A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.0.tgz", + "integrity": "sha512-HDg5Fyg3tENtmI5SpEL34TvEjIiVX4GhuOjU8aOGF7T4SMG69kLyx+IWMKhg39pBw+3h4lG6FDC8IfqYXONNLg==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-prohibited-strings": { @@ -4156,58 +14718,560 @@ } }, "remark-lint-rule-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-2.0.1.tgz", - "integrity": "sha512-hz4Ff9UdlYmtO6Czz99WJavCjqCer7Cav4VopXt+yVIikObw96G5bAuLYcVS7hvMUGqC9ZuM02/Y/iq9n8pkAg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.0.tgz", + "integrity": "sha512-KHSPHW/7YCl9gHFsqqWOqIkJYmPuxTu/5G3Ks3lG8seBDf1bg+lPPUg5TigsKa/E7juVgfTR7AhK6P+lYAp4EA==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-strong-marker": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-2.0.1.tgz", - "integrity": "sha512-8X2IsW1jZ5FmW9PLfQjkL0OVy/J3xdXLcZrG1GTeQKQ91BrPFyEZqUM2oM6Y4S6LGtxWer+neZkPZNroZoRPBQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.0.tgz", + "integrity": "sha512-nNyW3tKl0rEf2j784HzVWChAomCxzld+v2A5R5r5Zw5VogUNikZA7ZRwy51HsmhqiTWHArVGeyuvCPrpkTDZ0A==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-table-cell-padding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-3.0.0.tgz", - "integrity": "sha512-sEKrbyFZPZpxI39R8/r+CwUrin9YtyRwVn0SQkNQEZWZcIpylK+bvoKIldvLIXQPob+ZxklL0GPVRzotQMwuWQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.0.tgz", + "integrity": "sha512-jYBhfu/x0bEXt+wilHnm76q6wHnPVW2v2EuTdvAsxqkVtlvWSl9BbO4bb/L7jKqwlfiTK8E/luHKZuPiNWlucw==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-table-pipes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-3.0.0.tgz", - "integrity": "sha512-QPokSazEdl0Y8ayUV9UB0Ggn3Jos/RAQwIo0z1KDGnJlGDiF80Jc6iU9RgDNUOjlpQffSLIfSVxH5VVYF/K3uQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.0.tgz", + "integrity": "sha512-wOIAwkPAEDArKYMEpDylycGOCCt9hUxfgirgYCaHujCvyg484GWO+n+Moabgd19O9ZjuYr2P7akuOocsTh2z3g==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-lint-unordered-list-marker-style": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-2.0.1.tgz", - "integrity": "sha512-8KIDJNDtgbymEvl3LkrXgdxPMTOndcux3BHhNGB2lU4UnxSpYeHsxcDgirbgU6dqCAfQfvMjPvfYk19QTF9WZA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.0.tgz", + "integrity": "sha512-iwliMh7GzTdFAWKnVSabpdfcI6qoDE5PPX8hacDIZNbTe4xuUVFbopGCzsTlLiFQkTn6m3ePwOQn+lIbFofKDQ==", "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@types/mdast": "^3.0.0", + "unified": "^10.0.0", + "unified-lint-rule": "^2.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-position": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", + "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-message-control": { @@ -4228,45 +15292,44 @@ } }, "remark-preset-lint-node": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-2.4.1.tgz", - "integrity": "sha512-lNRqQulYuu8ADd4lSNhjOnZck/iDzLVY8oWA9U4BptfHQcDVwFm3bkNDfsVuEA7iJAFJzF7QuuHIcxzPV5VeFg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.0.tgz", + "integrity": "sha512-H1YwlVi/K0xmFT2JaVqnySNHdW/gqd9EQRbGVcH2mkxLNLdO+FIawkSU+UVYIhsm63pKAkHFW8HEtdoEAkNxOg==", "requires": { "js-yaml": "^4.0.0", - "remark-lint": "^8.0.0", - "remark-lint-blockquote-indentation": "^2.0.0", - "remark-lint-checkbox-character-style": "^3.0.0", - "remark-lint-checkbox-content-indent": "^3.0.0", - "remark-lint-code-block-style": "^2.0.0", - "remark-lint-definition-spacing": "^2.0.0", - "remark-lint-fenced-code-flag": "^2.0.0", - "remark-lint-fenced-code-marker": "^2.0.0", - "remark-lint-file-extension": "^1.0.3", - "remark-lint-final-definition": "^2.0.0", - "remark-lint-first-heading-level": "^2.0.0", - "remark-lint-heading-style": "^2.0.0", - "remark-lint-list-item-indent": "^2.0.0", - "remark-lint-maximum-line-length": "^2.0.0", - "remark-lint-no-consecutive-blank-lines": "^3.0.0", - "remark-lint-no-file-name-articles": "^1.0.4", - "remark-lint-no-file-name-consecutive-dashes": "^1.0.4", - "remark-lint-no-file-name-outer-dashes": "^1.0.5", - "remark-lint-no-heading-indent": "^3.0.0", - "remark-lint-no-multiple-toplevel-headings": "^2.0.0", - "remark-lint-no-shell-dollars": "^2.0.0", - "remark-lint-no-table-indentation": "^3.0.0", - "remark-lint-no-tabs": "^2.0.0", + "remark-lint-blockquote-indentation": "^3.0.0", + "remark-lint-checkbox-character-style": "^4.0.0", + "remark-lint-checkbox-content-indent": "^4.0.0", + "remark-lint-code-block-style": "^3.0.0", + "remark-lint-definition-spacing": "^3.0.0", + "remark-lint-fenced-code-flag": "^3.0.0", + "remark-lint-fenced-code-marker": "^3.0.0", + "remark-lint-file-extension": "^2.0.0", + "remark-lint-final-definition": "^3.0.0", + "remark-lint-first-heading-level": "^3.0.0", + "remark-lint-heading-style": "^3.0.0", + "remark-lint-list-item-indent": "^3.0.0", + "remark-lint-maximum-line-length": "^3.0.0", + "remark-lint-no-consecutive-blank-lines": "^4.0.0", + "remark-lint-no-file-name-articles": "^2.0.0", + "remark-lint-no-file-name-consecutive-dashes": "^2.0.0", + "remark-lint-no-file-name-outer-dashes": "^2.0.0", + "remark-lint-no-heading-indent": "^4.0.0", + "remark-lint-no-multiple-toplevel-headings": "^3.0.0", + "remark-lint-no-shell-dollars": "^3.0.0", + "remark-lint-no-table-indentation": "^4.0.0", + "remark-lint-no-tabs": "^3.0.0", "remark-lint-no-trailing-spaces": "^2.0.1", "remark-lint-prohibited-strings": "^2.0.0", - "remark-lint-rule-style": "^2.0.0", - "remark-lint-strong-marker": "^2.0.0", - "remark-lint-table-cell-padding": "^3.0.0", - "remark-lint-table-pipes": "^3.0.0", - "remark-lint-unordered-list-marker-style": "^2.0.0", - "remark-preset-lint-recommended": "^5.0.0", + "remark-lint-rule-style": "^3.0.0", + "remark-lint-strong-marker": "^3.0.0", + "remark-lint-table-cell-padding": "^4.0.0", + "remark-lint-table-pipes": "^4.0.0", + "remark-lint-unordered-list-marker-style": "^3.0.0", + "remark-preset-lint-recommended": "^6.0.0", "semver": "^7.3.2", - "unified-lint-rule": "^1.0.6", - "unist-util-visit": "^2.0.3" + "unified-lint-rule": "^2.0.0", + "unist-util-visit": "^4.0.0" }, "dependencies": { "argparse": { @@ -4274,6 +15337,16 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, "js-yaml": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", @@ -4281,30 +15354,247 @@ "requires": { "argparse": "^2.0.1" } + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-lint-rule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.0.tgz", + "integrity": "sha512-3V+eyHZR+PAeKavQrrvSacXq83C3TGVDZJpTZ8+MTlHZmS4arL1ul5U4WRymok0zobAsMiri42bJj0rCHIlIjA==", + "requires": { + "@types/unist": "^2.0.0", + "trough": "^2.0.0", + "unified": "^10.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.0.0.tgz", + "integrity": "sha512-3HWTvrtU10/E7qgPznBfiOyG0TXj9W8c1GSfaI8L9GkaG1pLePiQPZ7E35a0R3ToQ/zcy4Im6aZ9WBgOTnv1MQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + } + }, + "unist-util-visit-parents": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", + "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } } } }, "remark-preset-lint-recommended": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-5.0.0.tgz", - "integrity": "sha512-uu+Ab8JCwMMaKvvB0LOWTWtM3uAvJbKQM/oyWCEJqj7lUVNTKZS575Ro5rKM3Dx7kQjjR1iw0e99bpAYTc5xNA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.0.tgz", + "integrity": "sha512-ZVugDvBLFQ2JZ/tRIb0q/Oo4Qwp8s8AD8M/8GU7VgQYQ39GDVzo8lUTg2ugWy3YuBCX7wmnP0UDOSwIJt7vn0A==", "requires": { - "remark-lint": "^8.0.0", - "remark-lint-final-newline": "^1.0.0", - "remark-lint-hard-break-spaces": "^2.0.0", - "remark-lint-list-item-bullet-indent": "^3.0.0", - "remark-lint-list-item-indent": "^2.0.0", - "remark-lint-no-auto-link-without-protocol": "^2.0.0", - "remark-lint-no-blockquote-without-marker": "^4.0.0", - "remark-lint-no-duplicate-definitions": "^2.0.0", - "remark-lint-no-heading-content-indent": "^3.0.0", - "remark-lint-no-inline-padding": "^3.0.0", - "remark-lint-no-literal-urls": "^2.0.0", - "remark-lint-no-shortcut-reference-image": "^2.0.0", - "remark-lint-no-shortcut-reference-link": "^2.0.0", - "remark-lint-no-undefined-references": "^3.0.0", - "remark-lint-no-unused-definitions": "^2.0.0", - "remark-lint-ordered-list-marker-style": "^2.0.0" + "@types/mdast": "^3.0.0", + "remark-lint": "^9.0.0", + "remark-lint-final-newline": "^2.0.0", + "remark-lint-hard-break-spaces": "^3.0.0", + "remark-lint-list-item-bullet-indent": "^4.0.0", + "remark-lint-list-item-indent": "^3.0.0", + "remark-lint-no-auto-link-without-protocol": "^3.0.0", + "remark-lint-no-blockquote-without-marker": "^5.0.0", + "remark-lint-no-duplicate-definitions": "^3.0.0", + "remark-lint-no-heading-content-indent": "^4.0.0", + "remark-lint-no-inline-padding": "^4.0.0", + "remark-lint-no-literal-urls": "^3.0.0", + "remark-lint-no-shortcut-reference-image": "^3.0.0", + "remark-lint-no-shortcut-reference-link": "^3.0.0", + "remark-lint-no-undefined-references": "^4.0.0", + "remark-lint-no-unused-definitions": "^3.0.0", + "remark-lint-ordered-list-marker-style": "^3.0.0", + "unified": "^10.0.0" + }, + "dependencies": { + "bail": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.1.tgz", + "integrity": "sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==" + }, + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" + }, + "mdast-comment-marker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-2.0.0.tgz", + "integrity": "sha512-LQ4sf7vUzxz4mQQlzzBDgjaCJO5A0lkIAT9TyeNMfqaP31ooP1Qw9hprf7/V3NCo5FA1nvo5gbnfLVRY79QlDQ==" + }, + "remark-lint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.0.tgz", + "integrity": "sha512-ETO4zI48PR1Nz42YiyaYBzyhOiEfppXLnck7HW2pjKqxd36SIyQgM6sxD4ToMQI9KuCgy8mLAl/iVJoDLKxVjw==", + "requires": { + "@types/mdast": "^3.0.0", + "remark-message-control": "^7.0.0", + "unified": "^10.1.0" + } + }, + "remark-message-control": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-7.0.0.tgz", + "integrity": "sha512-KZySoC97TrMPYfIZ9vJ7wxvQwniy68K6WCY3vmSedDN5YuGfdVOpMj6sjaZQcqbWZV9n7BhrT70E3xaUTtk4hA==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-comment-marker": "^2.0.0", + "rehype": "^12.0.0", + "unified": "^10.0.0", + "unified-message-control": "^4.0.0", + "vfile": "^5.0.0" + } + }, + "trough": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", + "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + }, + "unified": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", + "integrity": "sha512-4U3ru/BRXYYhKbwXV6lU6bufLikoAavTwev89H5UxY8enDFaAT2VXmIXYNm6hb5oHPng/EXr77PVyDFcptbk5g==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unified-message-control": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-4.0.0.tgz", + "integrity": "sha512-1b92N+VkPHftOsvXNOtkJm4wHlr+UDmTBF2dUzepn40oy9NxanJ9xS1RwUBTjXJwqr2K0kMbEyv1Krdsho7+Iw==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^3.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "vfile-message": "^3.0.0" + } + }, + "unist-util-is": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", + "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" + }, + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", + "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^4.0.0" + } + }, + "unist-util-visit-parents": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", + "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, + "vfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.0.2.tgz", + "integrity": "sha512-5cV+K7tX83MT3bievROc+7AvHv0GXDB0zqbrTjbOe+HRbkzvY4EP+wS3IR77kUBCoWFMdG9py18t0sesPtQ1Rw==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-location": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.0.1.tgz", + "integrity": "sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==", + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "vfile-message": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.0.2.tgz", + "integrity": "sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + } } }, "remark-stringify": { @@ -4389,6 +15679,11 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "space-separated-tokens": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", + "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==" + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4412,6 +15707,22 @@ "strip-ansi": "^6.0.0" } }, + "stringify-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.1.tgz", + "integrity": "sha512-gmMQxKXPWIO3NXNSPyWNhlYcBNGpPA/487D+9dLPnU4xBnIrnHdr8cv5rGJOS/1BRxEXRb7uKwg7BA36IWV7xg==", + "requires": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^2.0.0" + }, + "dependencies": { + "character-entities-legacy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz", + "integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==" + } + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -4530,9 +15841,9 @@ } }, "unist-util-generated": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", + "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==" }, "unist-util-inspect": { "version": "5.0.1", @@ -4647,6 +15958,11 @@ "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==" }, + "web-namespaces": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.0.tgz", + "integrity": "sha512-dE7ELZRVWh0ceQsRgkjLgsAvwTuv3kcjSY/hLjqL0llleUlQBDjE9JkB9FCBY5F2mnFEwiyJoowl8+NVGHe8dw==" + }, "wrapped": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", diff --git a/tools/node-lint-md-cli-rollup/package.json b/tools/node-lint-md-cli-rollup/package.json index 5d8913fb497463..6357c6210d4127 100644 --- a/tools/node-lint-md-cli-rollup/package.json +++ b/tools/node-lint-md-cli-rollup/package.json @@ -14,7 +14,7 @@ "remark": "^13.0.0", "remark-gfm": "^1.0.0", "remark-lint": "^8.0.0", - "remark-preset-lint-node": "^2.3.0", + "remark-preset-lint-node": "^3.0.0", "unified-args": "^8.1.0" }, "main": "dist/index.js", diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/LICENSE old mode 100644 new mode 100755 index 4b1ad51b2f0efc..9e841e7a26e4eb --- a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/LICENSE +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/LICENSE @@ -1,21 +1,21 @@ - MIT License - - Copyright (c) Microsoft Corporation. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/README.md old mode 100644 new mode 100755 index 5c0a337afcdefa..120083c91f5602 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/README.md +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/README.md @@ -5,12 +5,12 @@ This package contains type definitions for Mdast (https://github.com/syntax-tree/mdast). # Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mdast +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mdast. -Additional Details - * Last updated: Sat, 07 Sep 2019 00:45:19 GMT - * Dependencies: @types/unist +### Additional Details + * Last updated: Fri, 16 Jul 2021 17:31:26 GMT + * Dependencies: [@types/unist](https://npmjs.com/package/@types/unist) * Global values: none # Credits -These definitions were written by Jun Lu . +These definitions were written by [Christian Murphy](https://github.com/ChristianMurphy), [Jun Lu](https://github.com/lujun2), [Remco Haszing](https://github.com/remcohaszing), and [Titus Wormer](https://github.com/wooorm). diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/package.json old mode 100644 new mode 100755 index 23e52f45be668e..cfd3ff28b002c8 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/package.json +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/mdast/package.json @@ -1,17 +1,33 @@ { "name": "@types/mdast", - "version": "3.0.3", + "version": "3.0.7", "description": "TypeScript definitions for Mdast", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mdast", "license": "MIT", "contributors": [ + { + "name": "Christian Murphy", + "url": "https://github.com/ChristianMurphy", + "githubUsername": "ChristianMurphy" + }, { "name": "Jun Lu", "url": "https://github.com/lujun2", "githubUsername": "lujun2" + }, + { + "name": "Remco Haszing", + "url": "https://github.com/remcohaszing", + "githubUsername": "remcohaszing" + }, + { + "name": "Titus Wormer", + "url": "https://github.com/wooorm", + "githubUsername": "wooorm" } ], "main": "", - "types": "index", + "types": "index.d.ts", "repository": { "type": "git", "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", @@ -21,6 +37,6 @@ "dependencies": { "@types/unist": "*" }, - "typesPublisherContentHash": "14d7fdbd7f31ef3975bd5e967ada84235c102b1be369cba397ced8b95ebe4e57", - "typeScriptVersion": "3.0" + "typesPublisherContentHash": "666079441041567c5bdfa2b8ff46e900b18d544357be5b8cdcecfb412129e903", + "typeScriptVersion": "3.6" } \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/README.md index 78a310d17c9fab..283ae4d3bfed1c 100755 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/README.md +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/README.md @@ -6,113 +6,11 @@ This package contains type definitions for Unist (https://github.com/syntax-tree # Details Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/unist. -## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/unist/index.d.ts) -````ts -// Type definitions for non-npm package Unist 2.0 -// Project: https://github.com/syntax-tree/unist -// Definitions by: bizen241 -// Jun Lu -// Hernan Rajchert -// Titus Wormer -// Junyoung Choi -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 3.0 - -/** - * Syntactic units in unist syntax trees are called nodes. - */ -export interface Node { - /** - * The variant of a node. - */ - type: string; - - /** - * Information from the ecosystem. - */ - data?: Data | undefined; - - /** - * Location of a node in a source document. - * Must not be present if a node is generated. - */ - position?: Position | undefined; - - [key: string]: unknown; -} - -/** - * Information associated by the ecosystem with the node. - * Space is guaranteed to never be specified by unist or specifications - * implementing unist. - */ -export interface Data { - [key: string]: unknown; -} - -/** - * Location of a node in a source file. - */ -export interface Position { - /** - * Place of the first character of the parsed source region. - */ - start: Point; - - /** - * Place of the first character after the parsed source region. - */ - end: Point; - - /** - * Start column at each index (plus start line) in the source region, - * for elements that span multiple lines. - */ - indent?: number[] | undefined; -} - -/** - * One place in a source file. - */ -export interface Point { - /** - * Line in a source file (1-indexed integer). - */ - line: number; - - /** - * Column in a source file (1-indexed integer). - */ - column: number; - /** - * Character in a source file (0-indexed integer). - */ - offset?: number | undefined; -} - -/** - * Nodes containing other nodes. - */ -export interface Parent extends Node { - /** - * List representing the children of a node. - */ - children: Node[]; -} - -/** - * Nodes containing a value. - */ -export interface Literal extends Node { - value: unknown; -} - -```` ### Additional Details - * Last updated: Fri, 02 Jul 2021 18:04:49 GMT + * Last updated: Thu, 15 Jul 2021 00:31:23 GMT * Dependencies: none * Global values: none # Credits -These definitions were written by [bizen241](https://github.com/bizen241), [Jun Lu](https://github.com/lujun2), [Hernan Rajchert](https://github.com/hrajchert), [Titus Wormer](https://github.com/wooorm), and [Junyoung Choi](https://github.com/rokt33r). +These definitions were written by [bizen241](https://github.com/bizen241), [Jun Lu](https://github.com/lujun2), [Hernan Rajchert](https://github.com/hrajchert), [Titus Wormer](https://github.com/wooorm), [Junyoung Choi](https://github.com/rokt33r), [Ben Moon](https://github.com/GuiltyDolphin), and [JounQin](https://github.com/JounQin). diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/package.json index d4d18b7cbe9b59..ab4403f506948c 100755 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/package.json +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/@types/unist/package.json @@ -1,6 +1,6 @@ { "name": "@types/unist", - "version": "2.0.4", + "version": "2.0.6", "description": "TypeScript definitions for Unist", "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/unist", "license": "MIT", @@ -29,6 +29,16 @@ "name": "Junyoung Choi", "url": "https://github.com/rokt33r", "githubUsername": "rokt33r" + }, + { + "name": "Ben Moon", + "url": "https://github.com/GuiltyDolphin", + "githubUsername": "GuiltyDolphin" + }, + { + "name": "JounQin", + "url": "https://github.com/JounQin", + "githubUsername": "JounQin" } ], "main": "", @@ -40,6 +50,6 @@ }, "scripts": {}, "dependencies": {}, - "typesPublisherContentHash": "373f3a8c09fdf9fa50470b9d6b720dbe014e0fe93cb797a34481c4231e8fab59", + "typesPublisherContentHash": "da5f2c3f967fa07869161991244bb7f9a237ac20494b902ffcb9108deb9b4e12", "typeScriptVersion": "3.6" } \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/debug/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/debug/package.json index da809d2b8d28b2..b7d70acb9bee82 100644 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/debug/package.json +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/debug/package.json @@ -1,6 +1,6 @@ { "name": "debug", - "version": "4.3.1", + "version": "4.3.2", "repository": { "type": "git", "url": "git://github.com/visionmedia/debug.git" diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/debug/src/common.js b/tools/node_modules/eslint-plugin-markdown/node_modules/debug/src/common.js index 392a8e005a063a..50ce2925101d73 100644 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/debug/src/common.js +++ b/tools/node_modules/eslint-plugin-markdown/node_modules/debug/src/common.js @@ -60,6 +60,8 @@ function setup(env) { function createDebug(namespace) { let prevTime; let enableOverride = null; + let namespacesCache; + let enabledCache; function debug(...args) { // Disabled? @@ -120,7 +122,17 @@ function setup(env) { Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, - get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + + return enabledCache; + }, set: v => { enableOverride = v; } @@ -149,6 +161,7 @@ function setup(env) { */ function enable(namespaces) { createDebug.save(namespaces); + createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; diff --git a/tools/node_modules/eslint/README.md b/tools/node_modules/eslint/README.md index c87d07e0dcd1ac..804310d8c1fb26 100644 --- a/tools/node_modules/eslint/README.md +++ b/tools/node_modules/eslint/README.md @@ -254,6 +254,16 @@ Toru Nagashima The people who review and fix bugs and help triage issues.
+ +
+Brett Zamir +
+
+ +
+Bryan Mishkin +
+

Pig Fang @@ -288,7 +298,7 @@ The following companies, organizations, and individuals support ESLint's ongoing

Automattic

Gold Sponsors

Nx (by Nrwl) Chrome's Web Framework & Tools Performance Fund Salesforce Airbnb Coinbase Substack

Silver Sponsors

Retool Liftoff

Bronze Sponsors

-

Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

+

Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks Practice Ignition

## Technology Sponsors diff --git a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js index ca298f9c356c3c..24f6a10d14b609 100644 --- a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js +++ b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js @@ -156,6 +156,9 @@ function calculateStatsPerFile(messages) { return messages.reduce((stat, message) => { if (message.fatal || message.severity === 2) { stat.errorCount++; + if (message.fatal) { + stat.fatalErrorCount++; + } if (message.fix) { stat.fixableErrorCount++; } @@ -168,6 +171,7 @@ function calculateStatsPerFile(messages) { return stat; }, { errorCount: 0, + fatalErrorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 @@ -183,12 +187,14 @@ function calculateStatsPerFile(messages) { function calculateStatsPerRun(results) { return results.reduce((stat, result) => { stat.errorCount += result.errorCount; + stat.fatalErrorCount += result.fatalErrorCount; stat.warningCount += result.warningCount; stat.fixableErrorCount += result.fixableErrorCount; stat.fixableWarningCount += result.fixableWarningCount; return stat; }, { errorCount: 0, + fatalErrorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 diff --git a/tools/node_modules/eslint/lib/cli.js b/tools/node_modules/eslint/lib/cli.js index f766764546cc5a..477310da5850e7 100644 --- a/tools/node_modules/eslint/lib/cli.js +++ b/tools/node_modules/eslint/lib/cli.js @@ -131,14 +131,16 @@ function translateOptions({ */ function countErrors(results) { let errorCount = 0; + let fatalErrorCount = 0; let warningCount = 0; for (const result of results) { errorCount += result.errorCount; + fatalErrorCount += result.fatalErrorCount; warningCount += result.warningCount; } - return { errorCount, warningCount }; + return { errorCount, fatalErrorCount, warningCount }; } /** @@ -314,9 +316,12 @@ const cli = { if (await printResults(engine, resultsToPrint, options.format, options.outputFile)) { // Errors and warnings from the original unfiltered results should determine the exit code - const { errorCount, warningCount } = countErrors(results); + const { errorCount, fatalErrorCount, warningCount } = countErrors(results); + const tooManyWarnings = options.maxWarnings >= 0 && warningCount > options.maxWarnings; + const shouldExitForFatalErrors = + options.exitOnFatalError && fatalErrorCount > 0; if (!errorCount && tooManyWarnings) { log.error( @@ -325,6 +330,10 @@ const cli = { ); } + if (shouldExitForFatalErrors) { + return 2; + } + return (errorCount || tooManyWarnings) ? 1 : 0; } diff --git a/tools/node_modules/eslint/lib/options.js b/tools/node_modules/eslint/lib/options.js index 92c140bd3c8b2e..e3661ec81d528f 100644 --- a/tools/node_modules/eslint/lib/options.js +++ b/tools/node_modules/eslint/lib/options.js @@ -290,6 +290,12 @@ module.exports = optionator({ default: "true", description: "Prevent errors when pattern is unmatched" }, + { + option: "exit-on-fatal-error", + type: "Boolean", + default: "false", + description: "Exit with exit code 2 in case of fatal error" + }, { option: "debug", type: "Boolean", diff --git a/tools/node_modules/eslint/lib/rules/comma-style.js b/tools/node_modules/eslint/lib/rules/comma-style.js index fbdecccaac2589..824ad89b2f9964 100644 --- a/tools/node_modules/eslint/lib/rules/comma-style.js +++ b/tools/node_modules/eslint/lib/rules/comma-style.js @@ -216,6 +216,8 @@ module.exports = { previousItemToken = tokenAfterItem ? sourceCode.getTokenBefore(tokenAfterItem) : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1]; + } else { + previousItemToken = currentItemToken; } }); diff --git a/tools/node_modules/eslint/lib/rules/consistent-return.js b/tools/node_modules/eslint/lib/rules/consistent-return.js index a250430cb766b5..0e20209af56b7f 100644 --- a/tools/node_modules/eslint/lib/rules/consistent-return.js +++ b/tools/node_modules/eslint/lib/rules/consistent-return.js @@ -104,18 +104,18 @@ module.exports = { } else if (node.type === "ArrowFunctionExpression") { // `=>` token - loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start; + loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc; } else if ( node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method) ) { // Method name. - loc = node.parent.key.loc.start; + loc = node.parent.key.loc; } else { // Function name or `function` keyword. - loc = (node.id || node).loc.start; + loc = (node.id || context.getSourceCode().getFirstToken(node)).loc; } if (!name) { diff --git a/tools/node_modules/eslint/lib/rules/curly.js b/tools/node_modules/eslint/lib/rules/curly.js index 92d31a6476e435..61dcd8024bbd2c 100644 --- a/tools/node_modules/eslint/lib/rules/curly.js +++ b/tools/node_modules/eslint/lib/rules/curly.js @@ -131,15 +131,6 @@ module.exports = { return token.value === "else" && token.type === "Keyword"; } - /** - * Gets the `else` keyword token of a given `IfStatement` node. - * @param {ASTNode} node A `IfStatement` node to get. - * @returns {Token} The `else` keyword token. - */ - function getElseKeyword(node) { - return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken); - } - /** * Determines whether the given node has an `else` keyword token as the first token after. * @param {ASTNode} node The node to check. @@ -361,7 +352,7 @@ module.exports = { if (this.expected) { context.report({ node, - loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + loc: body.loc, messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter", data: { name @@ -371,7 +362,7 @@ module.exports = { } else { context.report({ node, - loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + loc: body.loc, messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter", data: { name diff --git a/tools/node_modules/eslint/lib/rules/no-mixed-operators.js b/tools/node_modules/eslint/lib/rules/no-mixed-operators.js index 15eb20bed2a49e..5a2e139a620519 100644 --- a/tools/node_modules/eslint/lib/rules/no-mixed-operators.js +++ b/tools/node_modules/eslint/lib/rules/no-mixed-operators.js @@ -117,7 +117,7 @@ module.exports = { ], messages: { - unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'." + unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'. Use parentheses to clarify the intended order of operations." } }, diff --git a/tools/node_modules/eslint/lib/rules/operator-assignment.js b/tools/node_modules/eslint/lib/rules/operator-assignment.js index fdb0884922b654..a48d2725197055 100644 --- a/tools/node_modules/eslint/lib/rules/operator-assignment.js +++ b/tools/node_modules/eslint/lib/rules/operator-assignment.js @@ -76,8 +76,8 @@ module.exports = { fixable: "code", messages: { - replaced: "Assignment can be replaced with operator assignment.", - unexpected: "Unexpected operator assignment shorthand." + replaced: "Assignment (=) can be replaced with operator assignment ({{operator}}=).", + unexpected: "Unexpected operator assignment ({{operator}}=) shorthand." } }, @@ -113,6 +113,7 @@ module.exports = { context.report({ node, messageId: "replaced", + data: { operator }, fix(fixer) { if (canBeFixed(left) && canBeFixed(expr.left)) { const equalsToken = getOperatorToken(node); @@ -139,7 +140,8 @@ module.exports = { */ context.report({ node, - messageId: "replaced" + messageId: "replaced", + data: { operator } }); } } @@ -155,6 +157,7 @@ module.exports = { context.report({ node, messageId: "unexpected", + data: { operator: node.operator }, fix(fixer) { if (canBeFixed(node.left)) { const firstToken = sourceCode.getFirstToken(node); diff --git a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json index 80b8c9aeafd6a9..cf138d6f2c3b7c 100644 --- a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json +++ b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json @@ -1,6 +1,6 @@ { "name": "@babel/helper-validator-identifier", - "version": "7.14.5", + "version": "7.14.8", "description": "Validate identifier/keywords name", "repository": { "type": "git", diff --git a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array-factory.js b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array-factory.js index c7ff6a09a93881..406601c24714ac 100644 --- a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array-factory.js +++ b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array-factory.js @@ -495,7 +495,7 @@ class ConfigArrayFactory { basePath ); - if (fs.existsSync(ctx.filePath)) { + if (fs.existsSync(ctx.filePath) && fs.statSync(ctx.filePath).isFile()) { let configData; try { diff --git a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json index e79857f5553e99..35f5129707338c 100644 --- a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json +++ b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json @@ -1,6 +1,6 @@ { "name": "@eslint/eslintrc", - "version": "0.4.2", + "version": "0.4.3", "description": "The legacy ESLintRC config file format for ESLint", "main": "lib/index.js", "files": [ @@ -40,7 +40,7 @@ "eslint-plugin-jsdoc": "^32.2.0", "eslint-plugin-node": "^11.1.0", "eslint-release": "^3.1.2", - "fs-teardown": "^0.1.0", + "fs-teardown": "0.1.1", "mocha": "^8.1.1", "shelljs": "^0.8.4", "sinon": "^9.2.0", diff --git a/tools/node_modules/eslint/node_modules/acorn-jsx/package.json b/tools/node_modules/eslint/node_modules/acorn-jsx/package.json index f42a7ea1437c8c..6debde9caa30ba 100644 --- a/tools/node_modules/eslint/node_modules/acorn-jsx/package.json +++ b/tools/node_modules/eslint/node_modules/acorn-jsx/package.json @@ -2,7 +2,7 @@ "name": "acorn-jsx", "description": "Modern, fast React.js JSX parser", "homepage": "https://github.com/acornjs/acorn-jsx", - "version": "5.3.1", + "version": "5.3.2", "maintainers": [ { "name": "Ingvar Stepanyan", diff --git a/tools/node_modules/eslint/node_modules/chalk/package.json b/tools/node_modules/eslint/node_modules/chalk/package.json index c2d63f67e5e955..47c23f29068caa 100644 --- a/tools/node_modules/eslint/node_modules/chalk/package.json +++ b/tools/node_modules/eslint/node_modules/chalk/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "4.1.1", + "version": "4.1.2", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", diff --git a/tools/node_modules/eslint/node_modules/chalk/readme.md b/tools/node_modules/eslint/node_modules/chalk/readme.md index 851259216bc193..a055d21c97ed76 100644 --- a/tools/node_modules/eslint/node_modules/chalk/readme.md +++ b/tools/node_modules/eslint/node_modules/chalk/readme.md @@ -33,7 +33,7 @@

- +

@@ -48,6 +48,12 @@ and avoiding access controls. Keep your team and servers in sync with Doppler. +
+ +
+ UI Bakery +
+

diff --git a/tools/node_modules/eslint/node_modules/debug/package.json b/tools/node_modules/eslint/node_modules/debug/package.json index da809d2b8d28b2..b7d70acb9bee82 100644 --- a/tools/node_modules/eslint/node_modules/debug/package.json +++ b/tools/node_modules/eslint/node_modules/debug/package.json @@ -1,6 +1,6 @@ { "name": "debug", - "version": "4.3.1", + "version": "4.3.2", "repository": { "type": "git", "url": "git://github.com/visionmedia/debug.git" diff --git a/tools/node_modules/eslint/node_modules/debug/src/common.js b/tools/node_modules/eslint/node_modules/debug/src/common.js index 392a8e005a063a..50ce2925101d73 100644 --- a/tools/node_modules/eslint/node_modules/debug/src/common.js +++ b/tools/node_modules/eslint/node_modules/debug/src/common.js @@ -60,6 +60,8 @@ function setup(env) { function createDebug(namespace) { let prevTime; let enableOverride = null; + let namespacesCache; + let enabledCache; function debug(...args) { // Disabled? @@ -120,7 +122,17 @@ function setup(env) { Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, - get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + + return enabledCache; + }, set: v => { enableOverride = v; } @@ -149,6 +161,7 @@ function setup(env) { */ function enable(namespaces) { createDebug.save(namespaces); + createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; diff --git a/tools/node_modules/eslint/node_modules/flatted/README.md b/tools/node_modules/eslint/node_modules/flatted/README.md index 8fd5b4d82f4459..1f52cc5b3877ff 100644 --- a/tools/node_modules/eslint/node_modules/flatted/README.md +++ b/tools/node_modules/eslint/node_modules/flatted/README.md @@ -1,6 +1,6 @@ # flatted -[![Downloads](https://img.shields.io/npm/dm/flatted.svg)](https://www.npmjs.com/package/flatted) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/flatted/badge.svg?branch=master)](https://coveralls.io/github/WebReflection/flatted?branch=master) [![Build Status](https://travis-ci.org/WebReflection/flatted.svg?branch=master)](https://travis-ci.org/WebReflection/flatted) [![License: ISC](https://img.shields.io/badge/License-ISC-yellow.svg)](https://opensource.org/licenses/ISC) ![WebReflection status](https://offline.report/status/webreflection.svg) +[![Downloads](https://img.shields.io/npm/dm/flatted.svg)](https://www.npmjs.com/package/flatted) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/flatted/badge.svg?branch=main)](https://coveralls.io/github/WebReflection/flatted?branch=main) [![Build Status](https://travis-ci.com/WebReflection/flatted.svg?branch=main)](https://travis-ci.com/WebReflection/flatted) [![License: ISC](https://img.shields.io/badge/License-ISC-yellow.svg)](https://opensource.org/licenses/ISC) ![WebReflection status](https://offline.report/status/webreflection.svg) ![snow flake](./flatted.jpg) diff --git a/tools/node_modules/eslint/node_modules/flatted/package.json b/tools/node_modules/eslint/node_modules/flatted/package.json index 013728929103d3..60f79eb7304267 100644 --- a/tools/node_modules/eslint/node_modules/flatted/package.json +++ b/tools/node_modules/eslint/node_modules/flatted/package.json @@ -1,6 +1,6 @@ { "name": "flatted", - "version": "3.2.0", + "version": "3.2.2", "description": "A super light and fast circular JSON parser.", "unpkg": "min.js", "types": "types.d.ts", @@ -12,8 +12,9 @@ "rollup:babel": "rollup --config rollup/babel.config.js && sed -i.bck 's/^var /self./' index.js && rm -rf index.js.bck && drop-babel-typeof index.js", "min": "terser index.js -c -m -o min.js", "size": "cat index.js | wc -c;cat min.js | wc -c;gzip -c9 min.js | wc -c;cat min.js | brotli | wc -c; cat es.js | brotli | wc -c", - "coveralls": "nyc report --reporter=text-lcov | coveralls", - "test": "nyc node test/index.js" + "coveralls": "c8 report --reporter=text-lcov | coveralls", + "test": "c8 node test/index.js", + "test:php": "php php/test.php" }, "repository": { "type": "git", @@ -36,13 +37,13 @@ "@babel/core": "^7.14.6", "@babel/preset-env": "^7.14.7", "ascjs": "^5.0.1", + "c8": "^7.7.3", "circular-json": "^0.5.9", "circular-json-es6": "^2.0.2", "coveralls": "^3.1.1", "drop-babel-typeof": "^1.0.3", "jsan": "^3.1.13", - "nyc": "^15.1.0", - "rollup": "^2.52.6", + "rollup": "^2.52.8", "rollup-plugin-babel": "^4.4.0", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-terser": "^7.0.2", diff --git a/tools/node_modules/eslint/node_modules/flatted/php/test.php b/tools/node_modules/eslint/node_modules/flatted/php/test.php deleted file mode 100644 index 8b49e924842035..00000000000000 --- a/tools/node_modules/eslint/node_modules/flatted/php/test.php +++ /dev/null @@ -1,118 +0,0 @@ -o = &$o; - -console::assert(Flatted::stringify($a) === '[["0"]]', 'recursive Array'); -console::assert(Flatted::stringify($o) === '[{"o":"0"}]', 'recursive Object'); - -$b = Flatted::parse(Flatted::stringify($a)); -console::assert(is_array($b) && $b[0] === $b, 'restoring recursive Array'); - -$a[] = 1; -$a[] = 'two'; -$a[] = true; -$o->one = 1; -$o->two = 'two'; -$o->three = true; - -console::assert(Flatted::stringify($a) === '[["0",1,"1",true],"two"]', 'values in Array'); -console::assert(Flatted::stringify($o) === '[{"o":"0","one":1,"two":"1","three":true},"two"]', 'values in Object'); - -$a[] = &$o; -$o->a = &$a; - -console::assert(Flatted::stringify($a) === '[["0",1,"1",true,"2"],"two",{"o":"2","one":1,"two":"1","three":true,"a":"0"}]', 'object in Array'); -console::assert(Flatted::stringify($o) === '[{"o":"0","one":1,"two":"1","three":true,"a":"2"},"two",["2",1,"1",true,"0"]]', 'array in Object'); - -$a[] = array('test' => 'OK'); -$a[] = [1, 2, 3]; - -$o->test = array('test' => 'OK'); -$o->array = [1, 2, 3]; - -console::assert(Flatted::stringify($a) === '[["0",1,"1",true,"2","3","4"],"two",{"o":"2","one":1,"two":"1","three":true,"a":"0","test":"3","array":"4"},{"test":"5"},[1,2,3],"OK"]', 'objects in Array'); -console::assert(Flatted::stringify($o) === '[{"o":"0","one":1,"two":"1","three":true,"a":"2","test":"3","array":"4"},"two",["2",1,"1",true,"0","3","4"],{"test":"5"},[1,2,3],"OK"]', 'objects in Object'); - -$a2 = Flatted::parse(Flatted::stringify($a)); -$o2 = Flatted::parse(Flatted::stringify($o)); - -console::assert($a2[0] === $a2, 'parsed Array'); -console::assert($o2->o === $o2, 'parsed Object'); - -console::assert( - $a2[1] === 1 && - $a2[2] === 'two' && - $a2[3] === true && - $a2[4] instanceof stdClass && - json_encode($a2[5]) === json_encode(array('test' => 'OK')) && - json_encode($a2[6]) === json_encode([1, 2, 3]), - 'array values are all OK' -); - -console::assert($a2[4] === $a2[4]->o && $a2 === $a2[4]->o->a, 'array recursive values are OK'); - -console::assert( - $o2->one === 1 && - $o2->two === 'two' && - $o2->three === true && - is_array($o2->a) && - json_encode($o2->test) === json_encode(array('test' => 'OK')) && - json_encode($o2->array) === json_encode([1, 2, 3]), - 'object values are all OK' -); - -console::assert($o2->a === $o2->a[0] && $o2 === $o2->a[4], 'object recursive values are OK'); - -console::assert(Flatted::parse(Flatted::stringify(1)) === 1, 'numbers can be parsed too'); -console::assert(Flatted::parse(Flatted::stringify(false)) === false, 'booleans can be parsed too'); -console::assert(Flatted::parse(Flatted::stringify(null)) === null, 'null can be parsed too'); -console::assert(Flatted::parse(Flatted::stringify('test')) === 'test', 'strings can be parsed too'); - -$str = Flatted::parse('[{"prop":"1","a":"2","b":"3"},{"value":123},["4","5"],{"e":"6","t":"7","p":4},{},{"b":"8"},"f",{"a":"9"},["10"],"sup",{"a":1,"d":2,"c":"7","z":"11","h":1},{"g":2,"a":"7","b":"12","f":6},{"r":4,"u":"7","c":5}]'); - -console::assert( - $str->b->t->a === 'sup' && - $str->a[1]->b[0]->c === $str->b->t, - 'str is fine' -); - -$oo = Flatted::parse('[{"a":"1","b":"0","c":"2"},{"aa":"3"},{"ca":"4","cb":"5","cc":"6","cd":"7","ce":"8","cf":"9"},{"aaa":"10"},{"caa":"4"},{"cba":"5"},{"cca":"2"},{"cda":"4"},"value2","value3","value1"]'); - -console::assert( - $oo->a->aa->aaa = 'value1' - && $oo === $oo->b - && $oo === $oo->b - && $oo->c->ca->caa === $oo->c->ca - && $oo->c->cb->cba === $oo->c->cb - && $oo->c->cc->cca === $oo->c - && $oo->c->cd->cda === $oo->c->ca->caa - && $oo->c->ce === 'value2' - && $oo->c->cf === 'value3', - 'parse is correct' -); - -echo "OK\n"; - -?> \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/globals/globals.json b/tools/node_modules/eslint/node_modules/globals/globals.json index 1119914e203e2c..334ff3e01e9cc0 100644 --- a/tools/node_modules/eslint/node_modules/globals/globals.json +++ b/tools/node_modules/eslint/node_modules/globals/globals.json @@ -442,15 +442,24 @@ "CSSImportRule": false, "CSSKeyframeRule": false, "CSSKeyframesRule": false, + "CSSMatrixComponent": false, "CSSMediaRule": false, "CSSNamespaceRule": false, "CSSPageRule": false, + "CSSPerspective": false, + "CSSRotate": false, "CSSRule": false, "CSSRuleList": false, + "CSSScale": false, + "CSSSkew": false, + "CSSSkewX": false, + "CSSSkewY": false, "CSSStyleDeclaration": false, "CSSStyleRule": false, "CSSStyleSheet": false, "CSSSupportsRule": false, + "CSSTransformValue": false, + "CSSTranslate": false, "CustomElementRegistry": false, "customElements": false, "CustomEvent": false, diff --git a/tools/node_modules/eslint/node_modules/globals/package.json b/tools/node_modules/eslint/node_modules/globals/package.json index 66d027e5f30e8c..a646c1ded41493 100644 --- a/tools/node_modules/eslint/node_modules/globals/package.json +++ b/tools/node_modules/eslint/node_modules/globals/package.json @@ -1,6 +1,6 @@ { "name": "globals", - "version": "13.9.0", + "version": "13.10.0", "description": "Global identifiers from different JavaScript environments", "license": "MIT", "repository": "sindresorhus/globals", diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md index f1ff6731d37e2d..25cc428c27f613 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/README.md @@ -105,8 +105,8 @@ Performance of different validators by [json-schema-benchmark](https://github.co - Ajv implements JSON Schema [draft-06/07/2019-09/2020-12](http://json-schema.org/) standards (draft-04 is supported in v6): - all validation keywords (see [JSON Schema validation keywords](https://ajv.js.org/json-schema.html)) - [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md) extensions: - - NEW: keyword [discriminator](https://ajv.js.org/json-schema.md#discriminator). - - keyword [nullable](https://ajv.js.org/json-schema.md#nullable). + - NEW: keyword [discriminator](https://ajv.js.org/json-schema.html#discriminator). + - keyword [nullable](https://ajv.js.org/json-schema.html#nullable). - full support of remote references (remote schemas have to be added with `addSchema` or compiled to be available) - support of recursive references between schemas - correct string lengths for strings with unicode pairs @@ -161,6 +161,11 @@ const schema = { additionalProperties: false, } +const data = { + foo: 1, + bar: "abc" +} + const validate = ajv.compile(schema) const valid = validate(data) if (!valid) console.log(validate.errors) diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/errors.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/errors.js index 0dcf28bc5cd491..27b2091762c20f 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/errors.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/errors.js @@ -5,7 +5,7 @@ const codegen_1 = require("./codegen"); const util_1 = require("./util"); const names_1 = require("./names"); exports.keywordError = { - message: ({ keyword }) => codegen_1.str `should pass "${keyword}" keyword validation`, + message: ({ keyword }) => codegen_1.str `must pass "${keyword}" keyword validation`, }; exports.keyword$DataError = { message: ({ keyword, schemaType }) => schemaType diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/jtd/serialize.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/jtd/serialize.js index 69f0f563c7f128..7ca512d4399f7a 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/jtd/serialize.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/jtd/serialize.js @@ -180,7 +180,7 @@ function serializeType(cxt) { serializeString(cxt); break; case "timestamp": - gen.if(codegen_1._ `${data} instanceof Date`, () => gen.add(names_1.default.json, codegen_1._ `${data}.toISOString()`), () => serializeString(cxt)); + gen.if(codegen_1._ `${data} instanceof Date`, () => gen.add(names_1.default.json, codegen_1._ `'"' + ${data}.toISOString() + '"'`), () => serializeString(cxt)); break; default: serializeNumber(cxt); diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/index.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/index.js index 43371e7c7b51b8..a43053e228b6ca 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/index.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/index.js @@ -303,7 +303,10 @@ class KeywordCxt { } } result(condition, successAction, failAction) { - this.gen.if(codegen_1.not(condition)); + this.failResult(codegen_1.not(condition), successAction, failAction); + } + failResult(condition, successAction, failAction) { + this.gen.if(condition); if (failAction) failAction(); else @@ -322,7 +325,7 @@ class KeywordCxt { } } pass(condition, failAction) { - this.result(condition, undefined, failAction); + this.failResult(codegen_1.not(condition), undefined, failAction); } fail(condition) { if (condition === undefined) { diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/not.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/not.js index 60ad2b9a7c4dab..72f9f85a0ac8c2 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/not.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/not.js @@ -18,7 +18,7 @@ const def = { createErrors: false, allErrors: false, }, valid); - cxt.result(valid, () => cxt.error(), () => cxt.reset()); + cxt.failResult(valid, () => cxt.reset(), () => cxt.error()); }, error: { message: "must NOT be valid" }, }; diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json index 357ede01961155..6bf862d66f44ec 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.6.0", + "version": "8.6.2", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", @@ -70,7 +70,7 @@ "@rollup/plugin-typescript": "^8.2.1", "@types/chai": "^4.2.12", "@types/mocha": "^8.0.3", - "@types/node": "^15.0.2", + "@types/node": "^16.3.2", "@types/require-from-string": "^1.2.0", "@typescript-eslint/eslint-plugin": "^3.8.0", "@typescript-eslint/parser": "^3.8.0", @@ -83,7 +83,7 @@ "eslint": "^7.8.1", "eslint-config-prettier": "^7.0.0", "glob": "^7.0.0", - "husky": "^6.0.0", + "husky": "^7.0.1", "if-node-version": "^1.0.0", "jimp": "^0.16.1", "js-beautify": "^1.7.3", diff --git a/tools/node_modules/eslint/package.json b/tools/node_modules/eslint/package.json index ac3a78cc3b0f30..1845500824c9e5 100644 --- a/tools/node_modules/eslint/package.json +++ b/tools/node_modules/eslint/package.json @@ -1,6 +1,6 @@ { "name": "eslint", - "version": "7.30.0", + "version": "7.32.0", "author": "Nicholas C. Zakas ", "description": "An AST-based pattern checker for JavaScript.", "bin": { @@ -44,7 +44,7 @@ "bugs": "https://github.com/eslint/eslint/issues/", "dependencies": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "@eslint/eslintrc": "^0.4.3", "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -96,14 +96,14 @@ "ejs": "^3.0.2", "eslint": "file:.", "eslint-config-eslint": "file:packages/eslint-config-eslint", - "eslint-plugin-eslint-plugin": "^3.2.0", + "eslint-plugin-eslint-plugin": "^3.5.3", "eslint-plugin-internal-rules": "file:tools/internal-rules", "eslint-plugin-jsdoc": "^25.4.3", "eslint-plugin-node": "^11.1.0", "eslint-release": "^2.0.0", "eslump": "^3.0.0", "esprima": "^4.0.1", - "fs-teardown": "^0.1.0", + "fs-teardown": "0.1.1", "glob": "^7.1.6", "jsdoc": "^3.5.5", "karma": "^6.1.1", diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi index 68da6ef3378904..6bb08bcebeca91 100644 --- a/tools/v8_gypfiles/features.gypi +++ b/tools/v8_gypfiles/features.gypi @@ -261,7 +261,10 @@ 'defines': ['ENABLE_MINOR_MC',], }], ['v8_enable_pointer_compression==1', { - 'defines': ['V8_COMPRESS_POINTERS',], + 'defines': [ + 'V8_COMPRESS_POINTERS', + 'V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE', + ], }], ['v8_enable_pointer_compression==1 or v8_enable_31bit_smis_on_64bit_arch==1', { 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH',],