diff --git a/javascript-vendingmachine-precourse/.gitignore b/javascript-vendingmachine-precourse/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/javascript-vendingmachine-precourse/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/javascript-vendingmachine-precourse/.npmrc b/javascript-vendingmachine-precourse/.npmrc new file mode 100644 index 0000000..c42da84 --- /dev/null +++ b/javascript-vendingmachine-precourse/.npmrc @@ -0,0 +1 @@ +engine-strict = true diff --git a/javascript-vendingmachine-precourse/LICENSE b/javascript-vendingmachine-precourse/LICENSE new file mode 100644 index 0000000..2a91af0 --- /dev/null +++ b/javascript-vendingmachine-precourse/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 woowacourse + +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/javascript-vendingmachine-precourse/README.md b/javascript-vendingmachine-precourse/README.md new file mode 100644 index 0000000..aebfcb9 --- /dev/null +++ b/javascript-vendingmachine-precourse/README.md @@ -0,0 +1,206 @@ +

+ +

+

자판기

+ +## πŸ” 진행방식 + +- λ―Έμ…˜μ€ **κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­, ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­, 과제 μ§„ν–‰ μš”κ΅¬μ‚¬ν•­** μ„Έ κ°€μ§€λ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€. +- μ„Έ 개의 μš”κ΅¬μ‚¬ν•­μ„ λ§Œμ‘±ν•˜κΈ° μœ„ν•΄ λ…Έλ ₯ν•œλ‹€. 특히 κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κΈ° 전에 κΈ°λŠ₯ λͺ©λ‘μ„ λ§Œλ“€κ³ , κΈ°λŠ₯ λ‹¨μœ„λ‘œ 컀밋 ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ§„ν–‰ν•œλ‹€. +- κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­μ— κΈ°μž¬λ˜μ§€ μ•Šμ€ λ‚΄μš©μ€ 슀슀둜 νŒλ‹¨ν•˜μ—¬ κ΅¬ν˜„ν•œλ‹€. + + +## 🎯 κΈ°λŠ₯ μš”κ΅¬ 사항 +λ°˜ν™˜λ˜λŠ” 동전이 μ΅œμ†Œν•œμ΄ λ˜λŠ” 자판기λ₯Ό κ΅¬ν˜„ν•œλ‹€. +### 1) 곡톡 + +상단에 `νƒ­`메뉴가 μ‘΄μž¬ν•˜λ©° 각 탭에 따라 μ μ ˆν•œ κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€. + +- `μƒν’ˆ 관리`탭은 μžνŒκΈ°κ°€ λ³΄μœ ν•˜κ³  μžˆλŠ”Β **μƒν’ˆμ„ μΆ”κ°€**ν•˜λŠ” κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€. +- `μž”λˆ μΆ©μ „`탭은 **μžνŒκΈ°κ°€ λ³΄μœ ν•  κΈˆμ•‘μ„ μΆ©μ „**ν•˜λŠ” κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€. +- `μƒν’ˆ ꡬ맀`탭은 μ‚¬μš©μžκ°€Β **κΈˆμ•‘μ„ νˆ¬μž…**ν•  수 있으며, νˆ¬μž…ν•œ κΈˆμ•‘μ— 맞좰 **μƒν’ˆμ„ ꡬ맀**ν•˜κ³ , 남은 κΈˆμ•‘μ— λŒ€ν•΄μ„œλŠ”Β **μž”λˆμ„ λ°˜ν™˜**ν•˜λŠ” κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€. +- λ‹€λ₯Έ νƒ­μœΌλ‘œ μ΄λ™ν–ˆλ‹€ λŒμ•„μ™€λ„ κΈ°μ‘΄ νƒ­μ˜ μƒνƒœκ°€ μœ μ§€λ˜μ–΄μ•Ό ν•œλ‹€. +- localStorageλ₯Ό μ΄μš©ν•˜μ—¬, μƒˆλ‘œκ³ μΉ¨ν•˜λ”λΌλ„ κ°€μž₯ μ΅œκ·Όμ— μž‘μ—…ν•œ 정보듀을 뢈러올 수 μžˆλ„λ‘ ν•œλ‹€. + +### 2) μƒν’ˆ 관리 νƒ­ + +`μƒν’ˆ 관리`νƒ­μ—μ„œ, λ‹€μŒκ³Ό 같은 κ·œμΉ™μ„ λ°”νƒ•μœΌλ‘œ μƒν’ˆμ„ μΆ”κ°€ν•œλ‹€. + +- 졜초 μƒν’ˆ λͺ©λ‘μ€ λΉ„μ›Œμ§„ μƒνƒœμ΄λ‹€. +- μƒν’ˆλͺ…, 가격, μˆ˜λŸ‰μ„ μž…λ ₯ν•΄ μƒν’ˆμ„ μΆ”κ°€ν•  수 μžˆλ‹€. + - μƒν’ˆ 가격은 100원뢀터 μ‹œμž‘ν•˜λ©°, 10μ›μœΌλ‘œ λ‚˜λˆ„μ–΄ λ–¨μ–΄μ Έμ•Ό ν•œλ‹€. +- μ‚¬μš©μžλŠ” μΆ”κ°€ν•œ μƒν’ˆμ„ 확인할 수 μžˆλ‹€. + +### 3) μž”λˆ μΆ©μ „ νƒ­ (자판기 보유 동전) + +`μž”λˆ μΆ©μ „`Β νƒ­μ—μ„œ, λ‹€μŒκ³Ό 같은 κ·œμΉ™μœΌλ‘œ 자판기 보유 κΈˆμ•‘μ„ μΆ©μ „ν•œλ‹€. + +- `μž”λˆ μΆ©μ „`Β νƒ­μ—μ„œ 졜초 μžνŒκΈ°κ°€ λ³΄μœ ν•œ κΈˆμ•‘μ€ 0원이며, 각 λ™μ „μ˜ κ°œμˆ˜λŠ” 0κ°œμ΄λ‹€. +- μž”λˆ μΆ©μ „ μž…λ ₯ μš”μ†Œμ— μΆ©μ „ν•  κΈˆμ•‘μ„ μž…λ ₯ν•œ ν›„, `μΆ©μ „ν•˜κΈ°` λ²„νŠΌμ„ 눌러 자판기 보유 κΈˆμ•‘μ„ μΆ©μ „ν•  수 μžˆλ‹€. + - 자판기 보유 κΈˆμ•‘μ€Β `{κΈˆμ•‘}원`Β ν˜•μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Έλ‹€. +- 자판기 보유 κΈˆμ•‘λ§ŒνΌμ˜ 동전이 λ¬΄μž‘μœ„λ‘œ μƒμ„±λœλ‹€. + - λ™μ „μ˜ κ°œμˆ˜λŠ”Β `{개수}개`Β ν˜•μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Έλ‹€. +- 자판기 보유 κΈˆμ•‘μ„ λˆ„μ ν•˜μ—¬ μΆ©μ „ν•  수 μžˆλ‹€. μΆ”κ°€ μΆ©μ „ κΈˆμ•‘λ§ŒνΌμ˜ 동전이 λ¬΄μž‘μœ„λ‘œ μƒμ„±λ˜μ–΄ κΈ°μ‘΄ 동전듀에 더해진닀. +- μƒν’ˆ ꡬ맀 νƒ­μ—μ„œ νˆ¬μž…ν•œ κΈˆμ•‘μ€ 자판기 보유 κΈˆμ•‘μ— λ”ν•˜μ§€ μ•ŠλŠ”λ‹€. + +### 4) μƒν’ˆ ꡬ맀 νƒ­ + +`μƒν’ˆ ꡬ맀`νƒ­μ—μ„œ, λ‹€μŒκ³Ό 같은 κ·œμΉ™μ„ λ°”νƒ•μœΌλ‘œ κΈˆμ•‘μ„ μΆ©μ „ν•˜κ³ , μƒν’ˆμ„ κ΅¬λ§€ν•˜λ©°, μž”λˆμ„ λ°˜ν™˜ν•œλ‹€. + +- `μƒν’ˆ ꡬ맀`Β νŽ˜μ΄μ§€μ—μ„œ 졜초 μΆ©μ „ κΈˆμ•‘μ€ 0원이며, λ°˜ν™˜λœ 각 λ™μ „μ˜ κ°œμˆ˜λŠ” 0κ°œμ΄λ‹€. +- μ‚¬μš©μžλŠ” νˆ¬μž…ν•  κΈˆμ•‘ μž…λ ₯ μš”μ†Œμ— νˆ¬μž… κΈˆμ•‘μ„ μž…λ ₯ν•œ ν›„, `νˆ¬μž…ν•˜κΈ°`λ²„νŠΌμ„ μ΄μš©ν•˜μ—¬ κΈˆμ•‘μ„ νˆ¬μž…ν•œλ‹€. + - κΈˆμ•‘μ€ 10μ›μœΌλ‘œ λ‚˜λˆ„μ–΄ λ–¨μ–΄μ§€λŠ” κΈˆμ•‘λ§Œ νˆ¬μž…ν•  수 μžˆλ‹€. + - μžνŒκΈ°κ°€ λ³΄μœ ν•œ κΈˆμ•‘μ€Β `{κΈˆμ•‘}원`Β ν˜•μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Έλ‹€. +- κΈˆμ•‘μ€ λˆ„μ μœΌλ‘œ νˆ¬μž…ν•  수 μžˆλ‹€. +- ν’ˆμ ˆλœ μƒν’ˆμ˜ `κ΅¬λ§€ν•˜κΈ°` λ²„νŠΌμ€ disabled λ˜μ–΄μ•Ό ν•œλ‹€. +- μ‚¬μš©μžλŠ”Β `λ°˜ν™˜ν•˜κΈ°`Β λ²„νŠΌμ„ 톡해 μž”λˆμ„ λ°˜ν™˜ 받을 수 μžˆλ‹€. + +**μƒν’ˆ ꡬ맀 > μž”λˆ 계산 λͺ¨λ“ˆ** + +`μƒν’ˆ ꡬ맀`Β νƒ­μ—μ„œ μž”λˆ λ°˜ν™˜ μ‹œ λ‹€μŒκ³Ό 같은 κ·œμΉ™μ„ 톡해 μž”λˆμ„ λ°˜ν™˜ν•œλ‹€. + +- μž”λˆμ„ λŒλ €μ€„ λ•ŒλŠ” ν˜„μž¬ λ³΄μœ ν•œ μ΅œμ†Œ 개수의 λ™μ „μœΌλ‘œ μž”λˆμ„ λŒλ €μ€€λ‹€. +- 지폐λ₯Ό μž”λˆμœΌλ‘œ λ°˜ν™˜ν•˜λŠ” κ²½μš°λŠ” μ—†λ‹€κ³  κ°€μ •ν•œλ‹€. +- μž”λˆμ„ λ°˜ν™˜ν•  수 μ—†λŠ” 경우 μž”λˆμœΌλ‘œ λ°˜ν™˜ν•  수 μžˆλŠ” κΈˆμ•‘λ§Œ λ°˜ν™˜ν•œλ‹€. +- λ™μ „μ˜ 개수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •λ³΄λŠ”Β `{개수}개`Β ν˜•μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Έλ‹€. + +--- + +### πŸ’» μ‹€ν–‰ κ²°κ³Ό μ˜ˆμ‹œ + +#### μƒν’ˆ 관리 + + +#### μž”λˆ μΆ©μ „ + + +#### μƒν’ˆ ꡬ맀 및 μž”λˆ λ°˜ν™˜ + + +--- + +## βœ… ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬ 사항 + +### DOM μ„ νƒμž +각 μš”μ†Œμ— μ•„λž˜μ™€ 같은 μ„ νƒμžλ₯Ό λ°˜λ“œμ‹œ μ§€μ •ν•œλ‹€. + +**νƒ­ 메뉴 λ²„νŠΌ** + +- `μƒν’ˆ ꡬ맀` νƒ­μœΌλ‘œ μ΄λ™ν•˜λŠ” 메뉴 λ²„νŠΌ idλŠ”Β `product-purchase-menu`이닀. +- `μž”λˆ μΆ©μ „`νƒ­μœΌλ‘œ μ΄λ™ν•˜λŠ” 메뉴 λ²„νŠΌ idλŠ”Β `vending-machine-manage-menu`이닀. +- `μƒν’ˆ 관리`νƒ­μœΌλ‘œ μ΄λ™ν•˜λŠ” 메뉴 λ²„νŠΌ idλŠ”Β `product-add-menu`이닀. + +**μƒν’ˆ 관리(μΆ”κ°€) 메뉴** + +- μƒν’ˆ μΆ”κ°€ μž…λ ₯ 폼의 μƒν’ˆλͺ… μž…λ ₯ μš”μ†Œμ˜ idλŠ”Β `product-name-input`이닀. +- μƒν’ˆ μΆ”κ°€ μž…λ ₯ 폼의 μƒν’ˆ 가격 μž…λ ₯ μš”μ†Œμ˜ idλŠ”Β `product-price-input`이닀. +- μƒν’ˆ μΆ”κ°€ μž…λ ₯ 폼의 μˆ˜λŸ‰ μž…λ ₯ μš”μ†Œμ˜ idλŠ”Β `product-quantity-input`이닀. +- μƒν’ˆ `μΆ”κ°€ν•˜κΈ°` λ²„νŠΌ μš”μ†Œμ˜ idλŠ”Β `product-add-button`이닀. +- μΆ”κ°€ν•œ 각 μƒν’ˆ μš”μ†Œμ˜ classλͺ…은 `product-manage-item`이며, ν•˜μœ„μ— μ•„λž˜ μš”μ†Œλ“€μ„ κ°–λŠ”λ‹€. + - μƒν’ˆλͺ…에 ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-manage-name`이닀. + - 가격에 ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-manage-price`이닀. + - μˆ˜λŸ‰μ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-manage-quantity`이닀. + +**μž”λˆ μΆ©μ „ (자판기 보유 동전) 메뉴** + +- μžνŒκΈ°κ°€ λ³΄μœ ν•  κΈˆμ•‘μ„ μΆ©μ „ν•  μš”μ†Œμ˜ idλŠ”Β `vending-machine-charge-input`이닀. +- `μΆ©μ „ν•˜κΈ°`Β λ²„νŠΌμ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ idλŠ”Β `vending-machine-charge-button`이닀. +- μΆ©μ „λœ κΈˆμ•‘μ„ ν™•μΈν•˜λŠ” μš”μ†Œμ˜ idλŠ”Β `vending-machine-charge-amount` 이닀. +- λ³΄μœ ν•œ 각 λ™μ „μ˜ κ°œμˆ˜μ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ idλŠ” λ‹€μŒκ³Ό κ°™λ‹€. + - 500원:Β `vending-machine-coin-500-quantity` + - 100원:Β `vending-machine-coin-100-quantity` + - 50원:Β `vending-machine-coin-50-quantity` + - 10원:Β `vending-machine-coin-10-quantity` + +**μƒν’ˆ ꡬ맀 메뉴** + +- νˆ¬μž… κΈˆμ•‘ μž…λ ₯ μš”μ†Œμ˜ idλŠ”Β `charge-input`이닀. +- νˆ¬μž…ν•˜κΈ° λ²„νŠΌ μš”μ†Œμ˜ idλŠ”Β `charge-button`이닀. +- νˆ¬μž…ν•œ κΈˆμ•‘μ„ ν™•μΈν•˜λŠ” μš”μ†Œμ˜ idλŠ”Β `charge-amount`이닀. +- λ°˜ν™˜ν•˜κΈ° λ²„νŠΌ μš”μ†Œμ˜ idλŠ”Β `coin-return-button`이닀. +- λ°˜ν™˜λœ 각 λ™μ „μ˜ κ°œμˆ˜μ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ idλŠ” λ‹€μŒκ³Ό κ°™λ‹€. + - 500원:Β `coin-500-quantity` + - 100원:Β `coin-100-quantity` + - 50원:Β `coin-50-quantity` + - 10원:Β `coin-10-quantity` +- 각 μƒν’ˆ μš”μ†Œμ˜ classλͺ…은 `product-purchase-item`이고, ν•˜μœ„μ— μ•„λž˜ μš”μ†Œλ“€μ„ κ°–λŠ”λ‹€. + - ꡬ맀 λ²„νŠΌμ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `purchase-button`이닀. + - μƒν’ˆλͺ…에 ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-purchase-name`이닀. + - 가격에 ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-purchase-price`이닀. + - μˆ˜λŸ‰μ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œμ˜ classλͺ…은 `product-purchase-quantity`이닀. + - μƒν’ˆλͺ…은 `dataset` 속성을 μ‚¬μš©ν•˜κ³ Β `data-product-name`Β ν˜•μ‹μœΌλ‘œ μ €μž₯ν•œλ‹€. + - 가격은 `dataset` 속성을 μ‚¬μš©ν•˜κ³ Β `data-product-price`Β ν˜•μ‹μœΌλ‘œ μ €μž₯ν•œλ‹€. + - μˆ˜λŸ‰μ€Β `dataset` 속성을 μ‚¬μš©ν•˜κ³ Β `data-product-quantity`Β ν˜•μ‹μœΌλ‘œ μ €μž₯ν•œλ‹€. + + +--- + +### 라이브러리 +- μž”λˆμ„ λ¬΄μž‘μœ„λ‘œ μƒμ„±ν•˜λŠ” κΈ°λŠ₯은 [`MissionUtils` 라이브러리](https://github.com/woowacourse-projects/javascript-mission-utils#mission-utils)의 `Random.pickNumberInList`λ₯Ό μ‚¬μš©ν•΄ κ΅¬ν•œλ‹€. + - `MissionUtils` 라이브러리 μŠ€ν¬λ¦½νŠΈλŠ” `index.html`에 이미 ν¬ν•¨λ˜μ–΄ μ „μ—­ 객체에 μΆ”κ°€λ˜μ–΄ μžˆμœΌλ―€λ‘œ, λ”°λ‘œ `import` ν•˜μ§€ μ•Šμ•„λ„ κ΅¬ν˜„ μ½”λ“œ μ–΄λ””μ—μ„œλ“  μ‚¬μš©ν•  수 μžˆλ‹€. + + ```javascript + // ex) + const randomNumber = Random.pickNumberInList([10, 50, 100, 500]); + ``` + +--- + +### 곡톡 μš”κ΅¬μ‚¬ν•­ + +- 슀크립트 μΆ”κ°€ 외에 μ£Όμ–΄μ§„Β `index.html`νŒŒμΌμ€ μˆ˜μ •ν•  수 μ—†λ‹€. + - μŠ€νƒ€μΌ(css)은 채점 μš”μ†Œκ°€ μ•„λ‹ˆλ‹€. +- λͺ¨λ“  μ˜ˆμ™Έ λ°œμƒ 상황은 `alert`λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ μ²˜λ¦¬ν•œλ‹€. +- μ™ΈλΆ€ 라이브러리(jQuery, Lodash λ“±)λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ , 순수 Vanilla JS둜만 κ΅¬ν˜„ν•œλ‹€. +- **[μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œ μ»¨λ²€μ…˜](https://github.com/woowacourse/woowacourse-docs/tree/feature/styleguide/styleguide/javascript)을 μ§€ν‚€λ©΄μ„œ ν”„λ‘œκ·Έλž˜λ°** ν•œλ‹€. +- **indent(인덴트, λ“€μ—¬μ“°κΈ°) depthλ₯Ό 3이 λ„˜μ§€ μ•Šλ„λ‘ κ΅¬ν˜„ν•œλ‹€. 2κΉŒμ§€λ§Œ ν—ˆμš©**ν•œλ‹€. + - 예λ₯Ό λ“€μ–΄ whileλ¬Έ μ•ˆμ— if문이 있으면 λ“€μ—¬μ“°κΈ°λŠ” 2이닀. + - 힌트: indent(인덴트, λ“€μ—¬μ“°κΈ°) depthλ₯Ό μ€„μ΄λŠ” 쒋은 방법은 ν•¨μˆ˜(λ˜λŠ” λ©”μ†Œλ“œ)λ₯Ό λΆ„λ¦¬ν•˜λ©΄ λœλ‹€. +- **ν•¨μˆ˜(λ˜λŠ” λ©”μ†Œλ“œ)κ°€ ν•œ κ°€μ§€ 일만 ν•˜λ„λ‘ μ΅œλŒ€ν•œ μž‘κ²Œ** λ§Œλ“€μ–΄λΌ. +- λ³€μˆ˜ μ„ μ–Έμ‹œ `var` λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€. `const` 와 `let` 을 μ‚¬μš©ν•œλ‹€. + - [const](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) + - [let](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) +- `import` 문을 μ΄μš©ν•΄ 슀크립트λ₯Ό λͺ¨λ“ˆν™”ν•˜κ³  뢈러올 수 있게 λ§Œλ“ λ‹€. + - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) +- **ν•¨μˆ˜(λ˜λŠ” λ©”μ†Œλ“œ)의 길이가 15라인을 λ„˜μ–΄κ°€μ§€ μ•Šλ„λ‘ κ΅¬ν˜„ν•œλ‹€.** + - ν•¨μˆ˜(λ˜λŠ” λ©”μ†Œλ“œ)κ°€ ν•œ κ°€μ§€ 일만 잘 ν•˜λ„λ‘ κ΅¬ν˜„ν•œλ‹€. + +--- + +## πŸ“ 과제 μ§„ν–‰ μš”κ΅¬μ‚¬ν•­ +- λ―Έμ…˜μ€ [javascript-vendingmachine-precourse](https://github.com/woowacourse/javascript-vendingmachine-precourse/) μ €μž₯μ†Œλ₯Ό Fork/Cloneν•΄ μ‹œμž‘ν•œλ‹€. +- **κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κΈ° 전에 javascript-vendingmachine-precourse/docs/README.md νŒŒμΌμ— κ΅¬ν˜„ν•  κΈ°λŠ₯ λͺ©λ‘μ„ 정리**ν•΄ μΆ”κ°€ν•œλ‹€. +- **Git의 컀밋 λ‹¨μœ„λŠ” μ•ž λ‹¨κ³„μ—μ„œ README.md νŒŒμΌμ— μ •λ¦¬ν•œ κΈ°λŠ₯ λͺ©λ‘ λ‹¨μœ„**둜 μΆ”κ°€ν•œλ‹€. + - [AngularJS Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) μ°Έκ³ ν•΄ commit logλ₯Ό 남긴닀. +- 과제 μ§„ν–‰ 및 제좜 방법은 [ν”„λ¦¬μ½”μŠ€ 과제 제좜 λ¬Έμ„œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) λ₯Ό μ°Έκ³ ν•œλ‹€. + +## βœ‰οΈ λ―Έμ…˜ 제좜 방법 + +- λ―Έμ…˜ κ΅¬ν˜„μ„ μ™„λ£Œν•œ ν›„ GitHub을 톡해 μ œμΆœν•΄μ•Ό ν•œλ‹€. + - GitHub을 ν™œμš©ν•œ 제좜 방법은 [ν”„λ¦¬μ½”μŠ€ 과제 제좜 λ¬Έμ„œ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) λ₯Ό μ°Έκ³ ν•΄ μ œμΆœν•œλ‹€. +- GitHub에 λ―Έμ…˜μ„ μ œμΆœν•œ ν›„ [μš°μ•„ν•œν…Œν¬μ½”μŠ€ 지원 ν”Œλž«νΌ](https://apply.techcourse.co.kr) 에 μ ‘μ†ν•˜μ—¬ ν”„λ¦¬μ½”μŠ€ 과제λ₯Ό μ œμΆœν•œλ‹€. + - μžμ„Έν•œ 방법은 [링크](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse#제좜-κ°€μ΄λ“œ) λ₯Ό μ°Έκ³ ν•œλ‹€. + - **Pull Request만 보내고, 지원 ν”Œλž«νΌμ—μ„œ 과제λ₯Ό μ œμΆœν•˜μ§€ μ•ŠμœΌλ©΄ μ΅œμ’… μ œμΆœν•˜μ§€ μ•Šμ€ κ²ƒμœΌλ‘œ μ²˜λ¦¬λ˜λ‹ˆ μ£Όμ˜ν•œλ‹€.** + + +### 🚨 과제 제좜 μ „ 체크리슀트 - 0점 λ°©μ§€λ₯Ό μœ„ν•œ μ£Όμ˜μ‚¬ν•­ +- μš”κ΅¬μ‚¬ν•­μ— λͺ…μ‹œλœ 좜λ ₯κ°’ ν˜•μ‹μ„ μ§€ν‚€μ§€ μ•Šμ„ 경우 κΈ°λŠ₯ κ΅¬ν˜„μ„ λͺ¨λ‘ μ •μƒμ μœΌλ‘œ ν–ˆλ”λΌλ„ 0점으둜 μ²˜λ¦¬λœλ‹€. +- κΈ°λŠ₯ κ΅¬ν˜„μ„ μ™„λ£Œν•œ λ’€ μ•„λž˜ κ°€μ΄λ“œμ— 따라 ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œ λͺ¨λ“  ν…ŒμŠ€νŠΈκ°€ μ„±κ³΅ν•˜λŠ” μ§€ ν™•μΈν•œλ‹€. **ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•  경우 0점으둜 μ²˜λ¦¬λ˜λ―€λ‘œ, λ°˜λ“œμ‹œ 확인 ν›„ μ œμΆœν•œλ‹€.** + +### βœ”οΈ ν…ŒμŠ€νŠΈ μ‹€ν–‰ κ°€μ΄λ“œ +- ν…ŒμŠ€νŠΈ 싀행에 ν•„μš”ν•œ νŒ¨ν‚€μ§€ μ„€μΉ˜λ₯Ό μœ„ν•΄ `Node.js` 버전 `14` 이상이 ν•„μš”ν•˜λ‹€. +- λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄ νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•œλ‹€. +```bash +// {폴더 경둜}/javascript-vendingmachine-precourse/ μ—μ„œ +npm install +``` + +- μ„€μΉ˜κ°€ μ™„λ£Œλ˜μ—ˆλ‹€λ©΄, λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•œλ‹€. +```bash +// {폴더 경둜}/javascript-vendingmachine-precourse/ μ—μ„œ +npm run test +``` + +- μ•„λž˜μ™€ 같은 화면이 λ‚˜μ˜€λ©° λͺ¨λ“  ν…ŒμŠ€νŠΈκ°€ passν•œλ‹€λ©΄ 성곡! + +![ν…ŒμŠ€νŠΈ κ²°κ³Ό](./images/test_result.png) diff --git a/javascript-vendingmachine-precourse/cypress.json b/javascript-vendingmachine-precourse/cypress.json new file mode 100644 index 0000000..a78fa83 --- /dev/null +++ b/javascript-vendingmachine-precourse/cypress.json @@ -0,0 +1,9 @@ +{ + "integrationFolder": "test", + "testFiles": "*.spec.js", + "screenshotOnRunFailure": false, + "video": false, + "pluginsFile": false, + "supportFile": false, + "blockHosts": ["cdn.jsdelivr.net"] +} diff --git a/javascript-vendingmachine-precourse/images/beverage_icon.png b/javascript-vendingmachine-precourse/images/beverage_icon.png new file mode 100644 index 0000000..cfed9e2 Binary files /dev/null and b/javascript-vendingmachine-precourse/images/beverage_icon.png differ diff --git a/javascript-vendingmachine-precourse/images/demo_coin.gif b/javascript-vendingmachine-precourse/images/demo_coin.gif new file mode 100644 index 0000000..05457a2 Binary files /dev/null and b/javascript-vendingmachine-precourse/images/demo_coin.gif differ diff --git a/javascript-vendingmachine-precourse/images/demo_product.gif b/javascript-vendingmachine-precourse/images/demo_product.gif new file mode 100644 index 0000000..ce631e2 Binary files /dev/null and b/javascript-vendingmachine-precourse/images/demo_product.gif differ diff --git a/javascript-vendingmachine-precourse/images/demo_purchase.gif b/javascript-vendingmachine-precourse/images/demo_purchase.gif new file mode 100644 index 0000000..12e4470 Binary files /dev/null and b/javascript-vendingmachine-precourse/images/demo_purchase.gif differ diff --git a/javascript-vendingmachine-precourse/images/test_result.png b/javascript-vendingmachine-precourse/images/test_result.png new file mode 100644 index 0000000..c987571 Binary files /dev/null and b/javascript-vendingmachine-precourse/images/test_result.png differ diff --git a/javascript-vendingmachine-precourse/index.html b/javascript-vendingmachine-precourse/index.html new file mode 100644 index 0000000..47d57c5 --- /dev/null +++ b/javascript-vendingmachine-precourse/index.html @@ -0,0 +1,13 @@ + + + + + 자판기 + + + + +
+ + + diff --git a/javascript-vendingmachine-precourse/package-lock.json b/javascript-vendingmachine-precourse/package-lock.json new file mode 100644 index 0000000..6a972b5 --- /dev/null +++ b/javascript-vendingmachine-precourse/package-lock.json @@ -0,0 +1,3111 @@ +{ + "name": "javascript-vendingmachine-precourse", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "javascript-vendingmachine-precourse", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "cypress": "8.7.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "2.88.10", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz", + "integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@types/node": { + "version": "14.18.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", + "integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==", + "dev": true + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cypress": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.7.0.tgz", + "integrity": "sha512-b1bMC3VQydC6sXzBMFnSqcvwc9dTZMgcaOzT0vpSD+Gq1yFc+72JDWi55sfUK5eIeNLAtWOGy1NNb6UlhMvB+Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^2.88.6", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "^6.0.2", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.0", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.5", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "ramda": "~0.27.1", + "request-progress": "^3.0.0", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/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==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", + "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==", + "dev": true + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/listr2": { + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.5.tgz", + "integrity": "sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.4.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", + "dev": true + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rxjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", + "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", + "dev": true, + "dependencies": { + "tslib": "~2.1.0" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, + "@cypress/request": { + "version": "2.88.10", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz", + "integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + } + }, + "@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@types/node": { + "version": "14.18.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.0.tgz", + "integrity": "sha512-0GeIl2kmVMXEnx8tg1SlG6Gg8vkqirrW752KqolYo1PHevhhZN3bhJ67qHj+bQaINhX0Ra3TlWwRvMCd9iEfNQ==", + "dev": true + }, + "@types/sinonjs__fake-timers": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", + "dev": true + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", + "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-table3": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "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=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "cypress": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.7.0.tgz", + "integrity": "sha512-b1bMC3VQydC6sXzBMFnSqcvwc9dTZMgcaOzT0vpSD+Gq1yFc+72JDWi55sfUK5eIeNLAtWOGy1NNb6UlhMvB+Q==", + "dev": true, + "requires": { + "@cypress/request": "^2.88.6", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "^6.0.2", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.0", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.5", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "ramda": "~0.27.1", + "request-progress": "^3.0.0", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "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==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eventemitter2": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", + "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==", + "dev": true + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "requires": { + "async": "^3.2.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "requires": { + "ci-info": "^3.2.0" + } + }, + "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==", + "dev": true + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr2": { + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.5.tgz", + "integrity": "sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.4.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", + "dev": true + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "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=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "dev": true + }, + "ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", + "dev": true, + "requires": { + "throttleit": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rxjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", + "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", + "dev": true, + "requires": { + "tslib": "~2.1.0" + } + }, + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + } + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/javascript-vendingmachine-precourse/package.json b/javascript-vendingmachine-precourse/package.json new file mode 100644 index 0000000..5790c81 --- /dev/null +++ b/javascript-vendingmachine-precourse/package.json @@ -0,0 +1,28 @@ +{ + "name": "javascript-vendingmachine-precourse", + "version": "1.0.0", + "description": "μš°μ•„ν•œν…Œν¬μ½”μŠ€ ν”„λ¦¬μ½”μŠ€ 자판기 λ―Έμ…˜", + "dependencies": {}, + "devDependencies": { + "cypress": "8.7.0" + }, + "scripts": { + "test": "cypress run --browser chrome" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/woowacourse/javascript-vendingmachine-precourse.git" + }, + "keywords": [], + "author": "woowacourse", + "license": "MIT", + "bugs": { + "url": "https://github.com/woowacourse/javascript-vendingmachine-precourse/issues" + }, + "homepage": "https://github.com/woowacourse/javascript-vendingmachine-precourse#readme", + "engineStrict": true, + "engines": { + "npm": ">=6.0.0", + "node": ">=14.0.0" + } +} diff --git a/javascript-vendingmachine-precourse/src/App.js b/javascript-vendingmachine-precourse/src/App.js new file mode 100644 index 0000000..e1ebae9 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/App.js @@ -0,0 +1,71 @@ +import { $ } from './utils/dom.js'; +import ProductManageController from './ProductManage/ProductManageController.js'; +import ChangeManageController from './ChangeManage/ChangeManageController.js'; +import ProductPurchaseController from './ProductPurchase/ProductPurchaseController.js'; +import { validateProdList, validateChanges } from './utils/validation.js'; +import Dialog from './utils/dialog.js'; + +export default class App { + template = ` + + πŸ‘†λ©”λ‰΄ 클릭 μ‹œ, ν•΄λ‹Ή νŽ˜μ΄μ§€λ‘œ μ΄λ™λ©λ‹ˆλ‹€.πŸ‘† +
+ `; + + $target; // app + ProductManageController; // μƒν’ˆ 관리 controller + ChangeManageController; // μž”λˆ μΆ©μ „ controller + ProductManageController; // μƒν’ˆ ꡬ맀 controller + + constructor($target) { + this.$target = $target; + this.$target.innerHTML = this.template; + + this.productManageController = new ProductManageController(); + this.ChangeManageController = new ChangeManageController(); + this.ProductPurchaseController = new ProductPurchaseController(); + $('#vending-machine-menu').addEventListener('click', e => this.onClickMenu(e)); + this.renderProductManageMenu(); //μ΄ˆκΈ°μ— μƒν’ˆ 관리 νŽ˜μ΄μ§€λ‘œ λ‘œλ“œλ˜λ„λ‘ + } + + // 각 메뉴 클릭 μ‹œ νƒ­ 이동 + onClickMenu({ target }) { + switch (target.id) { + case 'product-add-menu': + this.renderProductManageMenu(); + break; + case 'vending-machine-manage-menu': + this.renderChangeManageMenu(); + break; + case 'product-purchase-menu': + this.renderProductPurchaseMenu(); + break; + } + } + + // μƒν’ˆ 관리 νƒ­ λ Œλ”λ§ + renderProductManageMenu() { + this.productManageController.renderProductAddMenu(); + } + + // μž”λˆ μΆ©μ „ νƒ­ λ Œλ”λ§ + renderChangeManageMenu() { + this.ChangeManageController.renderChangeManageMenu(); + } + + // μƒν’ˆ ꡬ맀 νƒ­ λ Œλ”λ§ + renderProductPurchaseMenu() { + try { + validateProdList(); //μƒν’ˆ λͺ©λ‘ 검사 + validateChanges(); //μž”λˆ ν˜„ν™© 검사 + } catch (error) { + Dialog.error(error); + return; + } + this.ProductPurchaseController.renderProductPurchaseMenu(); + } +} diff --git a/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageController.js b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageController.js new file mode 100644 index 0000000..f5b42e5 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageController.js @@ -0,0 +1,28 @@ +import { $ } from '../utils/dom.js'; +import ChangeManageModel from './ChangeManageModel.js'; +import ChangeManageView from './ChangeManageView.js'; + +// μž”λˆ μΆ©μ „ service (view, model μ‚¬μ΄μ—μ„œ 관리) +export default class ChangeManageController { + model; + view; + + constructor() { + this.model = new ChangeManageModel(); + this.view = new ChangeManageView(); + } + + renderChangeManageMenu() { + this.model.updateChangeInfo(); + this.view.render(this.model.changeInfo); + $('#vending-machine-charge-form').addEventListener('submitChange', ({ detail }) => + this.onSubmitChange(detail) + ); + } + + // μž”λˆ μž…λ ₯ μ‹œ, λͺ¨λΈκ³Ό λ·° μ—…λ°μ΄νŠΈ + onSubmitChange(changeInput) { + this.model.setChangeInfo(changeInput); + this.view.updateChangeInfo(this.model.changeInfo); + } +} diff --git a/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageModel.js b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageModel.js new file mode 100644 index 0000000..8cead6e --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageModel.js @@ -0,0 +1,47 @@ +import { getData, setData } from '../utils/storage.js'; + +export default class ChangeManageController { + changeInfo; + + get changeInfo() { + return this.changeInfo; + } + + setChangeInfo(changeInput) { + this.changeInfo.total += changeInput; + this.changeInfo.coins = this.convertChangeToCoins(changeInput); + setData('changeInfo', this.changeInfo); + } + + constructor() { + this.updateChangeInfo(); + } + + updateChangeInfo() { + const initCoins = { + coin500: 0, + coin100: 0, + coin50: 0, + coin10: 0, + }; + + this.changeInfo = getData('changeInfo') ?? { + total: 0, + coins: initCoins, + }; + } + + // μž”λˆ λ¬΄μž‘μœ„λ‘œ κ΅ν™˜ + convertChangeToCoins(changeInput) { + const { coins } = this.changeInfo; + while (changeInput !== 0) { + const convertedCoins = MissionUtils.Random.pickNumberInList([10, 50, 100, 500]); + // 남은 μž”λˆμ΄ 10원, λ³€ν™˜λ  동전이 500원일 λ•ŒλŠ” κ΅ν™˜ λΆˆκ°€ + if (changeInput >= convertedCoins) { + changeInput -= convertedCoins; + coins[`coin${convertedCoins}`] += 1; + } + } + return coins; + } +} diff --git a/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageView.js b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageView.js new file mode 100644 index 0000000..3958361 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ChangeManage/ChangeManageView.js @@ -0,0 +1,88 @@ +import { $ } from '../utils/dom.js'; +import Dialog from '../utils/dialog.js'; +import { validateChange } from '../utils/validation.js'; + +export default class ChangeManageView { + $vendingMachineChargeForm; + template = ` +
+
+
+ μž”λˆ μΆ©μ „ + + +
+ +
+
+

ν˜„μž¬ μž”λˆ

+
+
+
+ `; + + // 초기 λ Œλ”λ§ (μž”λˆ μΆ©μ „ 메뉴 + ν˜„μž¬ μž”λˆ) + render(changeInfo) { + $('#current-menu').innerHTML = this.template; + this.updateChangeInfo(changeInfo); + this.$vendingMachineChargeForm = $('#vending-machine-charge-form'); + this.$vendingMachineChargeForm.addEventListener('submit', e => this.onChangeInput(e)); + } + + updateChangeInfo(changeInfo) { + const { total, coins } = changeInfo; + $('#vending-machine-charge-amount').textContent = `ν˜„μž¬ 총앑: ${total}원`; + $('#current-charge-table').innerHTML = ''; + $('#current-charge-table').innerHTML = this.createChangeInfo(coins); + } + + createChangeInfo(coins) { + const { coin500, coin100, coin50, coin10 } = coins; + + return ` + + + 동전 + 개수 + + + + + 500원 + ${coin500}개 + + + 100원 + ${coin100}개 + + + 50원 + ${coin50}개 + + + 10원 + ${coin10}개 + + + `; + } + + onChangeInput(e) { + e.preventDefault(); + const [_, changeInput] = e.target; + + try { + validateChange(+changeInput.value); + Dialog.show('μž”λˆμ΄ μ„±κ³΅μ μœΌλ‘œ μΆ©μ „λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); + } catch (error) { + Dialog.error(error); + return; + } + + // μž”λˆ μΆ©μ „ 이벀트 λ°œμƒ + const newEvent = new CustomEvent('submitChange', { + detail: +changeInput.value, + }); + this.$vendingMachineChargeForm.dispatchEvent(newEvent); + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductManage/ProductManageController.js b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageController.js new file mode 100644 index 0000000..3e2464a --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageController.js @@ -0,0 +1,30 @@ +import { $ } from '../utils/dom.js'; +import ProductManageModel from './ProductManageModel.js'; +import ProductManageView from './ProductManageView.js'; + +// μƒν’ˆ 관리 Service +export default class ProductManageController { + model; + view; + + constructor() { + this.model = new ProductManageModel(); + this.view = new ProductManageView(); + } + + // μƒν’ˆ μΆ”κ°€ 메뉴 + renderProductAddMenu() { + this.model.updateProdList(); + this.view.render(this.model.productList); + // μƒν’ˆ μΆ”κ°€ 이벀트 ν•Έλ“€λŸ¬ 바인딩 + $('#product-add-form').addEventListener('addNewProd', ({ detail }) => + this.onAddNewProduct(detail) + ); + } + + // μƒν’ˆ μΆ”κ°€ 이벀트 ν•Έλ“€λŸ¬ (데이터(λͺ¨λΈ) μ—…λ°μ΄νŠΈ, λ·° μ—…λ°μ΄νŠΈ) + onAddNewProduct(newProduct) { + this.model.setProdList(newProduct); + this.view.updateProdTable(this.model.productList); + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductManage/ProductManageModel.js b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageModel.js new file mode 100644 index 0000000..3074722 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageModel.js @@ -0,0 +1,30 @@ +import { makeProductId } from '../utils/validation.js'; +import { getData, setData } from '../utils/storage.js'; + +// μƒν’ˆ 데이터 관리 +export default class ProductManageModel { + productList; + + get productList() { + return this.productList; + } + + setProdList({ prodName, prodPrice, prodQuantity }) { + const newProduct = { + id: makeProductId(), + name: prodName, + price: prodPrice, + quantity: prodQuantity, + }; + this.productList = [...this.productList, newProduct]; + setData('productList', this.productList); + } + + constructor() { + this.updateProdList(); + } + + updateProdList() { + this.productList = getData('productList') ?? []; + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductManage/ProductManageView.js b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageView.js new file mode 100644 index 0000000..fbbfebe --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductManage/ProductManageView.js @@ -0,0 +1,88 @@ +import { $ } from '../utils/dom.js'; +import { validateProdInfo } from '../utils/validation.js'; +import Dialog from '../utils/dialog.js'; + +// μƒν’ˆ λ·° 관리 +export default class ProductManageView { + $addProductForm; + template = ` +
+
+
+ μƒν’ˆ μΆ”κ°€ + + + + +
+
+
+

μƒν’ˆ ν˜„ν™©

+
+
+
+ `; + + // 초기 λ Œλ”λ§ + render(productList) { + $('#current-menu').innerHTML = this.template; + this.updateProdTable(productList); + this.$addProductForm = $('#product-add-form'); + this.$addProductForm.addEventListener('submit', e => this.onSubmitNewProd(e)); + } + + // μƒν’ˆ λͺ©λ‘ λ Œλ”λ§ + updateProdTable(productList) { + $('#current-product-table').innerHTML = ''; + $('#current-product-table').innerHTML = this.createProductList(productList); + } + + createProductList(productList) { + return ` + + + μƒν’ˆλͺ… + 가격 + μˆ˜λŸ‰ + + + + ${productList + .map( + prod => ` + + ${prod.name} + ${prod.price} + ${prod.quantity} + + ` + ) + .join('')} + + `; + } + + // μƒν’ˆ μΆ”κ°€ λ²„νŠΌ 클릭 이벀트 ν•Έλ“€λŸ¬ + onSubmitNewProd(e) { + e.preventDefault(); + const [_, prodNameInput, prodPriceInput, prodQuantityInput] = e.target; + const prodName = prodNameInput.value; + const prodPrice = +prodPriceInput.value; + const prodQuantity = +prodQuantityInput.value; + const newProd = { prodName, prodPrice, prodQuantity }; + + try { + validateProdInfo(newProd); + Dialog.show('μƒν’ˆμ΄ μ„±κ³΅μ μœΌλ‘œ μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); + } catch (error) { + Dialog.error(error); + return; + } + + // μƒν’ˆ μΆ”κ°€ 이벀트 λ°œμƒ + const newEvent = new CustomEvent('addNewProd', { + detail: newProd, + }); + this.$addProductForm.dispatchEvent(newEvent); + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseController.js b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseController.js new file mode 100644 index 0000000..85e2b18 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseController.js @@ -0,0 +1,71 @@ +import { $ } from '../utils/dom.js'; +import ProductPurchaseModel from './ProductPurchaseModel.js'; +import ProductPurchaseView from './ProductPurchaseView.js'; +import Dialog from '../utils/dialog.js'; + +export default class ProductPurchaseController { + model; + view; + + constructor() { + this.model = new ProductPurchaseModel(); + this.view = new ProductPurchaseView(); + } + + // μƒν’ˆ ꡬ맀 메뉴 λ Œλ”λ§ + renderProductPurchaseMenu() { + this.model.updateData(); + this.view.render({ + inserted: this.model.inserted, + productList: this.model.productList, + coinsForChange: this.model.coinsForChange, + }); + + // 이벀트 ν•Έλ“€λŸ¬ 바인딩 + // κΈˆμ•‘ νˆ¬μž… + $('#charge-input-form').addEventListener('insertCoin', ({ detail }) => + this.onInsertCoins(detail) + ); + + // μƒν’ˆ ꡬ맀 + $('#available-product-table').addEventListener('purchaseProduct', ({ detail }) => + this.onPurchaseProduct(detail) + ); + + // μž”λˆ λ°˜ν™˜ + $('#coin-return-button').addEventListener('returnChange', () => this.onReturnChange()); + } + + // κΈˆμ•‘ νˆ¬μž… 이벀트 ν•Έλ“€λŸ¬ + onInsertCoins(inserted) { + this.model.setInsertedCoin(inserted); + this.view.updateInsertCoins(this.model.inserted); + } + + // μƒν’ˆ ꡬ맀 이벀트 ν•Έλ“€λŸ¬ + onPurchaseProduct(prodId) { + try { + this.model.purchaseProduct(prodId); + Dialog.show('μƒν’ˆμ΄ μ •μƒμ μœΌλ‘œ κ΅¬λ§€λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); + } catch (error) { + Dialog.error(error); + return; + } + + this.view.updateInsertCoins(this.model.inserted); + this.view.updateProductList(this.model.productList); + } + + // μž”λˆ λ°˜ν™˜ 이벀트 ν•Έλ“€λŸ¬ + onReturnChange() { + try { + this.model.returnChange(); + } catch (error) { + Dialog.error(error); + return; + } + + this.view.updateInsertCoins(this.model.inserted); + this.view.updateReturnChange(this.model.coinsForChange); + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseModel.js b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseModel.js new file mode 100644 index 0000000..eb5dab1 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseModel.js @@ -0,0 +1,107 @@ +import { getData, setData } from '../utils/storage.js'; +import { ERRORS } from '../utils/constants.js'; + +export default class ProductPurchaseModel { + inserted; // νˆ¬μž… κΈˆμ•‘ + productList; // μƒν’ˆ λͺ©λ‘ + coinsForChange; // μž”λˆ ν˜„ν™© + initialChangInfo = { + total: 0, + coins: { + coin500: 0, + coin100: 0, + coin50: 0, + coin10: 0, + }, + }; + + // getter + get inserted() { + return this.inserted; + } + + get productList() { + return this.productList; + } + + get coinsForChange() { + return this.coinsForChange; + } + + // setter + setInsertedCoin(inserted) { + this.inserted += inserted; + setData('inserted', this.inserted); + } + + // 초기 데이터 μ—…λ°μ΄νŠΈ + constructor() { + this.updateData(); + } + + updateData() { + this.inserted = getData('inserted') ?? 0; + this.productList = getData('productList') ?? []; + this.coinsForChange = getData('coinsForChange') ?? { + coin500: 0, + coin100: 0, + coin50: 0, + coin10: 0, + }; + } + + // μƒν’ˆ ꡬ맀 + purchaseProduct(prodId) { + const target = this.productList.find(product => product.id === +prodId); + if (this.inserted < target.price) throw new Error(ERRORS.PURCHASE.LACK_INSERTED); + + if (target.quantity > 0) { + this.inserted -= target.price; // νˆ¬μž… κΈˆμ•‘ μ—…λ°μ΄νŠΈ + target.quantity--; + } + + setData('inserted', this.inserted); + setData('productList', this.productList); // μƒν’ˆ λͺ©λ‘ μ—…λ°μ΄νŠΈ + } + + // μž”λˆ λ°˜ν™˜ + returnChange() { + // κΈˆμ•‘μ„ νˆ¬μž…ν•˜μ§€ μ•Šκ³  μž”λˆμ„ λ°˜ν™˜ν•˜λ €κ³  ν•  λ•Œ + if (this.inserted === 0) throw new Error(ERRORS.PURCHASE.EMPTY_INSERTED); + + const { total, coins } = getData('changeInfo'); + // ν˜„μž¬ νˆ¬μž…κΈˆμ•‘μ΄ μž”λˆλ³΄λ‹€ λ§Žμ„ λ•Œ + if (this.inserted >= total) { + this.coinsForChange = coins; + setData('changeInfo', this.initialChangInfo); + this.inserted -= total; + } else { + this.coinsForChange = this.convertChangeToCoins(this.inserted, this.coinsForChange); + setData('changeInfo', { + total: total - this.inserted, + coins: { + coin500: coins.coin500 - this.coinsForChange.coin500, + coin100: coins.coin100 - this.coinsForChange.coin100, + coin50: coins.coin50 - this.coinsForChange.coin50, + coin10: coins.coin10 - this.coinsForChange.coin10, + }, + }); + this.inserted = 0; + } + + setData('inserted', this.inserted); + setData('coinsForChange', this.coinsForChange); + } + + convertChangeToCoins(changeInput, coins) { + while (changeInput !== 0) { + const convertedCoins = MissionUtils.Random.pickNumberInList([10, 50, 100, 500]); + // 남은 μž”λˆμ΄ 10원, λ³€ν™˜λ  동전이 500원일 λ•ŒλŠ” κ΅ν™˜ λΆˆκ°€ + if (changeInput >= convertedCoins) { + changeInput -= convertedCoins; + coins[`coin${convertedCoins}`] += 1; + } + } + return coins; + } +} diff --git a/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseView.js b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseView.js new file mode 100644 index 0000000..77302a3 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/ProductPurchase/ProductPurchaseView.js @@ -0,0 +1,162 @@ +import { $ } from '../utils/dom.js'; +import Dialog from '../utils/dialog.js'; +import { validateChange } from '../utils/validation.js'; + +export default class ProductPurchaseView { + template = ` +
+
+
+ κΈˆμ•‘ νˆ¬μž… + + +
+ + νˆ¬μž…ν•œ κΈˆμ•‘: 원 + +
+
+

ꡬ맀할 수 μžˆλŠ” μƒν’ˆ ν˜„ν™©

+
+
+
+

λ°˜ν™˜λœ μž”λˆ

+ +
+
+
+ `; + + // 초기 λ Œλ”λ§ + render({ inserted, productList, coinsForChange }) { + $('#current-menu').innerHTML = this.template; + this.updateInsertCoins(inserted); // νˆ¬μž… κΈˆμ•‘ + this.updateProductList(productList); // μƒν’ˆ 리슀트 + this.updateReturnChange(coinsForChange); // μž”λˆ ν˜„ν™© + $('#charge-input-form').addEventListener('submit', e => this.onInsertCoin(e)); + $('#available-product-table').addEventListener('click', e => this.onClickPurchaseProduct(e)); + $('#coin-return-button').addEventListener('click', () => this.onClickReturnChange()); + } + x; + + // νˆ¬μž… κΈˆμ•‘ λ·° μ—…λ°μ΄νŠΈ + updateInsertCoins(inserted) { + $('#charge-amount').textContent = `${inserted}`; + } + + // μƒν’ˆ λͺ©λ‘ λ·° μ—…λ°μ΄νŠΈ + updateProductList(productList) { + $('#available-product-table').innerHTML = ''; + $('#available-product-table').innerHTML = this.createProductList(productList); + } + + // μž”λˆ λ°˜ν™˜ λ·° μ—…λ°μ΄νŠΈ + updateReturnChange(coinsForChange) { + $('#coin-return-table').innerHTML = ''; + $('#coin-return-table').innerHTML = this.createReturnChange(coinsForChange); + } + + // κΈˆμ•‘ νˆ¬μž… 이벀트 emit + onInsertCoin(e) { + e.preventDefault(); + const [_, chargeInput] = e.target; + try { + validateChange(+chargeInput.value); + Dialog.show('κΈˆμ•‘μ΄ μ •μƒμ μœΌλ‘œ νˆ¬μž…λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); + } catch (error) { + Dialog.error(error); + return; + } + + const newEvent = new CustomEvent('insertCoin', { + detail: +chargeInput.value, + }); + $('#charge-input-form').dispatchEvent(newEvent); + } + + // μƒν’ˆ ꡬ맀 이벀트 emit + onClickPurchaseProduct({ target }) { + if (target.className === 'purchase-button') { + const { productId } = target.closest('.product-purchase-item').dataset; + const newEvent = new CustomEvent('purchaseProduct', { + detail: productId, + }); + $('#available-product-table').dispatchEvent(newEvent); + } + } + + // μž”λˆ λ°˜ν™˜ 이벀트 emit + onClickReturnChange() { + const newEvent = new CustomEvent('returnChange'); + $('#coin-return-button').dispatchEvent(newEvent); + } + + // ν…œν”Œλ¦Ώ μ—…λ°μ΄νŠΈ + createProductList(productList) { + return ` + + + μƒν’ˆλͺ… + 가격 + μˆ˜λŸ‰ + ꡬ맀 + + + + ${productList + .map( + prod => ` + + ${prod.name} + ${ + prod.price + } + ${ + prod.quantity + } + + ${ + prod.quantity === 0 + ? `` + : `` + } + + + ` + ) + .join('')} + + `; + } + + createReturnChange(coinsForChange) { + const { coin500, coin100, coin50, coin10 } = coinsForChange; + + return ` + + + 동전 + 개수 + + + + + 500원 + ${coin500}개 + + + 100원 + ${coin100}개 + + + 50원 + ${coin50}개 + + + 10원 + ${coin10}개 + + +`; + } +} diff --git a/javascript-vendingmachine-precourse/src/index.js b/javascript-vendingmachine-precourse/src/index.js new file mode 100644 index 0000000..794d4fc --- /dev/null +++ b/javascript-vendingmachine-precourse/src/index.js @@ -0,0 +1,4 @@ +import App from './App.js'; +import { $ } from './utils/dom.js'; + +new App($('#app')); diff --git a/javascript-vendingmachine-precourse/src/utils/constants.js b/javascript-vendingmachine-precourse/src/utils/constants.js new file mode 100644 index 0000000..e9317ee --- /dev/null +++ b/javascript-vendingmachine-precourse/src/utils/constants.js @@ -0,0 +1,25 @@ +export const ERRORS = { + PROD_ADD: { + EMPTY_PROD_NAME: 'μƒν’ˆλͺ…을 μž…λ ₯ν•΄μ£Όμ„Έμš”.', + WRONG_PROD_PRICE: 'μƒν’ˆμ˜ 가격은 0원보닀 큰 κ°’μœΌλ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”.', + WRONG_PRICE_UNIT: 'μƒν’ˆ 가격은 10의 배수둜 μž…λ ₯ν•΄μ£Όμ„Έμš”.', + WRONG_QUANTITY: 'μƒν’ˆ μˆ˜λŸ‰μ€ 0보닀 큰 κ°’μœΌλ‘œ μž…λ ₯ν•΄μ£Όμ„Έμš”.', + DUPLICATE_PROD_NAME: '이미 λ“±λ‘λœ μƒν’ˆμž…λ‹ˆλ‹€.', + }, + CHANGE: { + EMPTY_CHANGE_AMOUNT: 'μΆ©μ „ κΈˆμ•‘μ€ 0원보닀 큰 값을 μž…λ ₯ν•΄μ£Όμ„Έμš”.', + WRONG_CHANGE_UNIT: 'μΆ©μ „ κΈˆμ•‘μ€ 10의 배수둜 μž…λ ₯ν•΄μ£Όμ„Έμš”.', + }, + PURCHASE: { + EMPTY_PRODUCT_LIST: 'λ“±λ‘λœ μƒν’ˆμ΄ μ—†μŠ΅λ‹ˆλ‹€. μƒν’ˆμ„ λ“±λ‘ν•΄μ£Όμ„Έμš”.', + EMPTY_CHANGE: 'μž”λˆμ΄ λΆ€μ‘±ν•΄ μƒν’ˆμ„ ꡬ맀할 수 μ—†μŠ΅λ‹ˆλ‹€. μž”λˆμ„ μΆ©μ „ν•΄μ£Όμ„Έμš”.', + LACK_INSERTED: 'ν˜„μž¬ νˆ¬μž…λœ κΈˆμ•‘μœΌλ‘œ ν•΄λ‹Ή μƒν’ˆμ„ ꡬ맀할 수 μ—†μŠ΅λ‹ˆλ‹€.', + EMPTY_INSERTED: 'νˆ¬μž…λœ κΈˆμ•‘μ΄ μ—†μŠ΅λ‹ˆλ‹€.', + }, +}; + +export const ERROR_BOUNDARIES = { + PRODUCT_ADD: { + MINIMUM_PRICE: 0, + }, +}; diff --git a/javascript-vendingmachine-precourse/src/utils/dialog.js b/javascript-vendingmachine-precourse/src/utils/dialog.js new file mode 100644 index 0000000..13389d4 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/utils/dialog.js @@ -0,0 +1,8 @@ +export default class Dialog { + static show(message) { + window.alert(message); + } + static error({ message }) { + window.alert(message); + } +} diff --git a/javascript-vendingmachine-precourse/src/utils/dom.js b/javascript-vendingmachine-precourse/src/utils/dom.js new file mode 100644 index 0000000..8f16fcc --- /dev/null +++ b/javascript-vendingmachine-precourse/src/utils/dom.js @@ -0,0 +1 @@ +export const $ = selector => document.querySelector(selector); diff --git a/javascript-vendingmachine-precourse/src/utils/storage.js b/javascript-vendingmachine-precourse/src/utils/storage.js new file mode 100644 index 0000000..eb117ab --- /dev/null +++ b/javascript-vendingmachine-precourse/src/utils/storage.js @@ -0,0 +1,3 @@ +// 둜컬 μŠ€ν† λ¦¬μ§€ get, set +export const getData = key => JSON.parse(window.localStorage.getItem(key)); +export const setData = (key, data) => window.localStorage.setItem(key, JSON.stringify(data)); diff --git a/javascript-vendingmachine-precourse/src/utils/validation.js b/javascript-vendingmachine-precourse/src/utils/validation.js new file mode 100644 index 0000000..2cf5e52 --- /dev/null +++ b/javascript-vendingmachine-precourse/src/utils/validation.js @@ -0,0 +1,48 @@ +import { ERRORS, ERROR_BOUNDARIES } from './constants.js'; +import { getData } from './storage.js'; + +// μƒν’ˆ μΆ”κ°€ - μƒν’ˆ 아이디 생성 +export const makeProductId = () => + Math.max(...(getData('productList') ?? []).map(prod => prod.id), 0) + 1; + +// μƒν’ˆ μΆ”κ°€ - μœ νš¨μ„± 검사 +export const validateProdInfo = ({ prodName, prodPrice, prodQuantity }) => { + // μƒν’ˆλͺ… λ―Έμž…λ ₯ + if (!prodName.trim().length) throw new Error(ERRORS.PROD_ADD.EMPTY_PROD_NAME); + + // μƒν’ˆ μ΅œμ†Œ κΈˆμ•‘ 미만 + if (prodPrice <= ERROR_BOUNDARIES.PRODUCT_ADD.MINIMUM_PRICE) + throw new Error(ERRORS.PROD_ADD.WRONG_PROD_PRICE); + + // μƒν’ˆ 가격 이상 + if (prodPrice % 10 !== 0) throw new Error(ERRORS.PROD_ADD.WRONG_PRICE_UNIT); + + // μƒν’ˆ μˆ˜λŸ‰ 이상 + if (prodQuantity <= 0) throw new Error(ERRORS.PROD_ADD.WRONG_QUANTITY); + + // μƒν’ˆ 쀑볡 + if ((getData('productList') ?? []).map(prod => prod.name).includes(prodName)) + throw new Error(ERRORS.PROD_ADD.DUPLICATE_PROD_NAME); +}; + +// μž”λˆ κ΅ν™˜ - μœ νš¨μ„± 검사 +export const validateChange = changeInput => { + // μž”λˆμ΄ 0원 μ΄ν•˜λ‘œ μž…λ ₯된 경우 + if (changeInput <= 0) throw new Error(ERRORS.CHANGE.EMPTY_CHANGE_AMOUNT); + + // μž”λˆ λ‹¨μœ„ 이상 + if (changeInput % 10 !== 0) throw new Error(ERRORS.CHANGE.WRONG_CHANGE_UNIT); +}; + +// μƒν’ˆ ꡬ맀 - λ“±λ‘λœ μƒν’ˆ μ—¬λΆ€ 확인 +export const validateProdList = () => { + const productList = getData('productList') ?? null; + if (!productList) throw new Error(ERRORS.PURCHASE.EMPTY_PRODUCT_LIST); +}; + +// μƒν’ˆ ꡬ맀 - μž”λˆ 확인 +export const validateChanges = () => { + const changeInfo = getData('changeInfo') ?? 0; + if (!changeInfo) throw new Error(ERRORS.PURCHASE.EMPTY_CHANGE); + changeInfo; +}; diff --git a/javascript-vendingmachine-precourse/style.css b/javascript-vendingmachine-precourse/style.css new file mode 100644 index 0000000..2e882bc --- /dev/null +++ b/javascript-vendingmachine-precourse/style.css @@ -0,0 +1,25 @@ +section { + margin: 20px; +} + +button { + border: 1px solid black; + border-radius: 3px; + background-color: white; + font-size: medium; + margin: 10px; +} + +table, +tr, +th, +td { + border: 1px solid #282828; + padding: 10px; + border-collapse: collapse; + text-align: center; +} + +fieldset { + margin-bottom: 20px; +} diff --git a/javascript-vendingmachine-precourse/test/app.spec.js b/javascript-vendingmachine-precourse/test/app.spec.js new file mode 100644 index 0000000..0a09605 --- /dev/null +++ b/javascript-vendingmachine-precourse/test/app.spec.js @@ -0,0 +1,116 @@ +describe("κ΅¬ν˜„ κ²°κ³Όκ°€ μš”κ΅¬μ‚¬ν•­κ³Ό μΌμΉ˜ν•΄μ•Ό ν•œλ‹€.", () => { + const baseUrl = "../index.html"; + const SELECTOR = { + COIN_MENU: "#vending-machine-manage-menu", + COIN_CHARGE_INPUT: "#vending-machine-charge-input", + COIN_CHARGE_BUTTON: "#vending-machine-charge-button", + COIN_500: "#vending-machine-coin-500-quantity", + COIN_100: "#vending-machine-coin-100-quantity", + COIN_50: "#vending-machine-coin-50-quantity", + COIN_10: "#vending-machine-coin-10-quantity", + PRODUCT_MENU: "#product-add-menu", + PRODUCT_NAME_INPUT: "#product-name-input", + PRODUCT_PRICE_INPUT: "#product-price-input", + PRODUCT_QUANTITY_INPUT: "#product-quantity-input", + PRODUCT_ADD_BUTTON: "#product-add-button", + PURCHASE_MENU: "#product-purchase-menu", + PURCHASE_CHARGE_INPUT: "#charge-input", + PURCHASE_CHARGE_AMOUNT: "#charge-amount", + PURCHASE_CHARGE_BUTTON: "#charge-button", + PURCHASE_ITEM_BUTTON: ".purchase-button", + PURCHASE_ITEM_QUANTITY: ".product-purchase-quantity", + }; + + before(() => { + Cypress.Commands.add("stubRandomReturns", (returnValues = []) => { + const randomStub = cy.stub(); + + returnValues.forEach((value, index) => { + randomStub.onCall(index).returns(value); + }); + + cy.visit(baseUrl, { + onBeforeLoad: (window) => { + window.MissionUtils = { + Random: { + pickNumberInList: randomStub, + }, + }; + }, + }); + }); + + Cypress.Commands.add("addProduct", (name, price, quantity) => { + cy.get(SELECTOR.PRODUCT_NAME_INPUT).type(name); + cy.get(SELECTOR.PRODUCT_PRICE_INPUT).type(price); + cy.get(SELECTOR.PRODUCT_QUANTITY_INPUT).type(quantity); + cy.get(SELECTOR.PRODUCT_ADD_BUTTON).click(); + }); + }); + + beforeEach(() => { + cy.stubRandomReturns([100, 100, 100, 100, 50]); + }); + + it("μƒν’ˆ 1개λ₯Ό ꡬ맀할 수 μžˆμ–΄μ•Ό ν•œλ‹€.", () => { + // given + const name = "콜라"; + const price = 1500; + const quantity = 20; + const coinAmount = 450; + const chargeAmount = 3000; + + // μƒν’ˆ μΆ”κ°€ + cy.get(SELECTOR.PRODUCT_MENU).click(); + cy.addProduct(name, price, quantity); + cy.addProduct("사이닀", 1000, 10); + + // μž”λˆ μΆ©μ „ + cy.get(SELECTOR.COIN_MENU).click(); + cy.get(SELECTOR.COIN_CHARGE_INPUT).type(coinAmount); + cy.get(SELECTOR.COIN_CHARGE_BUTTON).click(); + + // κΈˆμ•‘ νˆ¬μž… + cy.get(SELECTOR.PURCHASE_MENU).click(); + cy.get(SELECTOR.PURCHASE_CHARGE_INPUT).type(chargeAmount); + cy.get(SELECTOR.PURCHASE_CHARGE_BUTTON).click(); + + // when + cy.get("[data-product-name='콜라']") + .parent() + .find(SELECTOR.PURCHASE_ITEM_BUTTON) + .click(); + + // then + cy.get(SELECTOR.PURCHASE_CHARGE_AMOUNT).should( + "have.text", + chargeAmount - price + ); + cy.get("[data-product-name='콜라']") + .parent() + .find(SELECTOR.PURCHASE_ITEM_QUANTITY) + .should("have.text", quantity - 1); + cy.get(SELECTOR.COIN_MENU).click(); + cy.get(SELECTOR.COIN_100).should("have.text", "4개"); + cy.get(SELECTOR.COIN_50).should("have.text", "1개"); + }); + + it("잘λͺ»λœ μž…λ ₯κ°’μœΌλ‘œ μž”λˆ 좩전을 μ‹œλ„ν•˜λŠ” 경우 alert이 ν˜ΈμΆœλ˜μ–΄μ•Ό ν•œλ‹€.", () => { + // given + const alertStub = cy.stub(); + const invalidInput = -1; + + cy.on("window:alert", alertStub); + + // when + cy.get(SELECTOR.COIN_MENU).click(); + cy.get(SELECTOR.COIN_CHARGE_INPUT).type(invalidInput); + + // then + cy.get(SELECTOR.COIN_CHARGE_BUTTON) + .click() + .then(() => { + expect(alertStub).to.be.called; + }); + }); +});